I want to insert datas an existing Excel (.xls) file with Ruby under Linux. This file has already data, it has some format properties and it contains macros.
I tried to insert data into the file with the spreadsheet gem but when I save modifications, the format and all the macros of the file are lost.
Here's an example of a simple modification where I meet this problem :
book = Spreadsheet.open('myOriginalFile.xls')
sheet = book.worksheet 0
sheet.write('C12','hello')
book.write('myModifiedFile.xls')
I tried lots of things, did research on forums and the web but I didn't find a solution... Does anyone has an idea?
Macros can be stored inside xlsm file. If the Excel file extension is . xlsm, the file may contain macros. But the old Excel file format xls may or may not contain macros.
First, we will select the file for which we want to change the format. Then we will click righto open a list of options. Then we will click on the option of properties. After that we will select the option of type of file.
I found a solution :
I use the POI library of Apache which is written in java with the rjb gem (Ruby Java Bridge, which allows to use java libraries with ruby). POI allows to keep macros and formulas of existing xls file and to modify it.
For those who need, here's how to set up rjb to use POI :
# JVM loading
apache_poi_path = File.dirname(__FILE__)+'/poi-3.8/poi-3.8-20120326.jar'
Rjb::load("#{apache_poi_path}", ['-Xmx512M'])
# Java classes import
@file_class = Rjb::import('java.io.FileOutputStream')
@workbook_class = Rjb::import('org.apache.poi.hssf.usermodel.HSSFWorkbook')
@poifs_class = Rjb::import('org.apache.poi.poifs.filesystem.POIFSFileSystem')
Rjb::import('org.apache.poi.hssf.usermodel.HSSFCreationHelper')
Rjb::import('org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator')
@cell_reference_class = Rjb::import('org.apache.poi.hssf.util.CellReference')
@cell_class = Rjb::import('org.apache.poi.hssf.usermodel.HSSFCell')
# You can import all java classes that you need
# Java classes utilisation :
@file_input_class = Rjb::import('java.io.FileInputStream')
@file_input = @file_input_class.new(model_file_path)
@fs = @poifs_class.new(@file_input)
@book = @workbook_class.new(@fs)
@worksheet = @book.getSheet('worksheet')
# ...
# You can use your objects like in Java but with a ruby syntax
You need to write the modified file to a new file name. Check out this
If you have more than one sheet, you need to rewrite other sheets
XLS with several sheets but only modify one of the sheets (and don't touch the other data), there is no way, that spreadsheet "remembers" what is in the other sheets. You will have to write the unmodified sheets as well or otherwise unexpected things will happen.
Ergo: Write the modified sheet and also write the complete unmodified sheets again, when modifying an XLS with spreadsheet with several sheets.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With