Update cell values referenced by a formula with RubyXL - ruby

I have a xlsx with values in cells, many of them are referenced with a formula in other cell (in the same sheet). Im working with RubyXL because i wasn't found another gem which help me to write, edit and save an existed xlsx file.
Now to be clear, lets see an example of what im doing and i want.
Imagine a group of 3 cells; A1, B1 and C1 where C1 is the sum of A1 and B1 (=A1+B1), so if we have a 4 in A1, a 6 in B1 then C1 is equivalent to 10. I'm opening the xlsx with workbook = RubyXL::Parser.parse('example.xlsx'), afther that i modify the value of cell A1 from 4 to 5 and save it. Here is the problem, if we read the cell C1 after the change we still have the previous result 10.
How i can update that accord to the formula? Is posible with RubyXL? or is there another solution?

The problem with the accepted answer is that on servers office often isn't installed, so the COM automation won't work there.
When you use the following code the formulas are recalculated when Excel opens the spreadsheet.
workbook = RubyXL::Parser.parse(file)
workbook.calc_pr.full_calc_on_load = true

From the RubyXL README it sounds like that utility is intended to read Excel files and then write them back out. Then when you opened the file in Excel you would see your changes and the formulas would be recalculated.
You might want to look at win32ole if you want to do COM automation of Excel.

Finally i solved this. If you are interested I used win32ole because after tested a lot of rubygems this was the unic which works like i said in the question.
require 'win32ole'
begin
xl = WIN32OLE.new('Excel.Application')
workbook = xl.Workbooks.Open('my_route')
worksheet = workbook.Worksheets(1)
# Here we make operations like this one...
worksheet.Cells(2,2).value = 2
# After any operations we can see the results of referenced cells inmediatly
# Save the file if you want
# workbook.Save
workbook.Close
rescue => e
xl.Quit
end
So in conclusion RubyXL work fine but dont reflect the results of cells referenced in formulas when you edit the file. win32ole do that.

Related

Update existing excel file template formulas using ruby

I had been using spreadsheet to read in a template excel file, modify it and output a new file for the end-user.
As far as I can identify from the documentation spreadsheet provides no way to input or edit formulas in the produced document.
However, the purpose of my script is to read an undefined number of items from a site and enter them into the spreadsheet, then calculate totals and subtotals.
The end user (using excel or libreoffice etc) is then able to make slight modifications to the quantity of items whilst the totals update (due to formulas) as they are accustomed.
I have looked into the writeexcel gem which claims to be able to input formulas, but I can't see how to take an existing template file and modify it to produce my output. I can only create fresh workbooks.
Any tips please? I do not want to use Win32OLE.
This is surprisingly difficult; apparently all Gems for handling Excel files are missing some crucial functionality.
I can think of two approaches for this problem:
use a combination of spreadsheet (to read the Excel file) and use writeexcel (to write the output file)
use an input file that already contains the required formulas on a separate "formula" sheet and copies the formulas to the "real" sheet
Here's a simplistic version of the second approach:
require 'rubygems'
require 'spreadsheet'
Dir.chdir(File.dirname(__FILE__))
# input file, contains this data
# Sheet0: headers + data (for this simple demo, we will generate the data on-the-fly)
# Sheet1: Formula '=SUM(Worksheet1.A2:A255) in cell A1
book = Spreadsheet.open 'in.xls'
sheet = book.worksheet 0
formulasheet = book.worksheet 1
# insert some input data (in a real application,
# this data would already be present in the input sheet)
rows = rand(20) + 1
(1..rows).each do |i|
sheet[i,0] = i
end
# add total at bottom of column C
sheet[rows+1,2] = formulasheet[0,0]
# write output file
book.write 'out.xls'
However, this will fail if
you're using the same column for your input data and your totals (since then, the total will try to include itself in the calculation)

Editing a spreadsheet using SPREADSHEET ruby gem

I have to read data from a spread sheet modify some rows and then write the updated rows / cells into the same file.
I have used Spreadsheet gem with Ruby 2.0.0.
When I write the results back to the same file, I am unable to open the xls any more. I get an error
"File Format is not Valid"
in MS Excel.
When the updates are written onto a different file, I am able to open the file but it is in protected view. Is there a solution to this issue?
Below is the sample code:
require 'rubygems'
require 'spreadsheet'
book = Spreadsheet::open('filePath')
sheet = book.worksheet 0
## have application logic in here
book.write('filePath')
I've worked with this problem a few times and they've had the issue on log for around a year now.
The first problem is that it locks the file when spreadsheet loads it and there is no clear way to close it the only way I've been able to get it to not lock is with this code block. It opens it and stores the first worksheet off into its own variable then closes the file.
worksheet = nil
Spreadsheet.open workbook_name do |inner_book|
worksheet = inner_book.worksheet 0
end
worksheet
If you want all the worksheets you could do something similar. In addition to the file opening closing/problem you have the issue around capturing the content of the worksheet depending on the format. I know for my purposes I end up doing the following to capture the content. This sadly loses any formatting you might have had in the source spreadsheet.
rows = []
worksheet.each do |row|
rows << row
end
You can then make your own workbook/sheet and iterate through the rows and add them to the new sheet/book. Then save the new book with the same file name.
Its not fun or efficient, but it is a way to go about solving the problem. Hope this helped.
check your file extension.
spreadsheet, writeexcel..etc gems seem couldn't work with xlsx files.
try .xls not .xlsx

How to read excel values using queries in ruby?

I need to read an Excel sheet(.xls) values with Ruby using query. Is there any gems available in ruby to do this? If so please help me on this.
Any tips or advice on this would be great.
Thanks
Anto
You can use Sequel and OLEDB to read Excel Files:
require 'sequel'
Encoding.default_external = 'utf-8' #needed for umlauts in excel
def read_excel(source)
source = File.expand_path(source) #Full path needed
db = Sequel.ado(:conn_string=>"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=#{source};Extended Properties=Excel 8.0;")
# Excel 2000 (for table names, use a dollar after the sheet name, e.g. Sheet1$)
p db.test_connection
dataset = db[:'Tabelle1$']
p dataset
dataset.each{|row|
puts row
}
end #test_read
read_excel('my_spreadsheet.xls')
You should know the name of the tab (in my example it's Tabelle1)
The 'real' solution here is not Sequel, but the ADO-Interface. I'm not familiar with other ORM, so I may not really help you. But you may check for example active record.
There are hints, how to connect MS-Access or sqlserver via ADO, some use ActiveRecord.
If you replace the connection string with the Excel-String in my Sequel example, then you may use other ORMs.
You may also try to read Excel-Data via an ODBC-connection.
Read data from excel file using spreadsheet gem
require 'spreadsheet'
doc = Spreadsheet.open('simple.xls')
sheet = doc.worksheet(0) # list number, first list is 0 and so on...
val = sheet2[r,c] # read particular cell from list 0, r for row, c for column
Some information is there.
More information on the net, just use Google.

Rails 3 - Export to Excel with gridlines

What can I add to this method to force full gridlines in Excel export?
def export_invoices
headers['Content-Type'] = "application/vnd.ms-excel"
headers['Content-Disposition'] = 'attachment; filename="Invoices.xls"'
headers['Cache-Control'] = ''
#invoices = Invoice.all
render :layout => nil
end
Thanks!
Hmm, lots of things going on here that I don't think make sense. The line
#invoices = Invoice.all
results in SQL like SELECT "invoices".* FROM "invoices" -- the * means you want all columns from the table, and the .all means you want all the invoices, not just one. Unless the contents of the table is a single column binary type, I cannot see this working, since Excel's file format is vendor-specific binary (I think!).
Are you using some gem like paperclip or other to handle saving files? Unless you are manipulating the actual excel data from within Rails (perhaps with a gem that knows how to do this), either the file was saved with gridlines on, or not.
This page describes how you can format your Excel file using XML.
If I understand you question correctly, you are looking to style the output in excel. To do that you need to actually generate an office open XML document, not dump CSV with application headers.
Have a look at these two gems
http://rubygems.org/gems/axlsx
http://rubygems.org/gems/acts_as_xlsx
They should give you what you want.

Microsoft Excel spreadsheet used as a computation engine called from code

I have a MS Excel spreadsheet which does some complex computations. I'd like to create a script which will create a CSV file with the results obtained from the spreadsheet.
I could rewrite the logic from the spreadsheet in my programming language (for example Ruby, but I'm open to use a different language), but then I would have to update my code whenever someone changes the logic in the spreadsheet. Is it possible to use a MS Excel spreadsheet as a black box, a computation engine, which can be invoked from my code? Then I would only have write the CSV part and input data download in my code, the whole computation logic could stay in the spreadsheet and could be easily updated.
Ideally, I don't want to add any CSV generation or data download code to the spreadsheet, because it's used by domain-experts (not programmers). Additionally, I have to download some data from the Internet and pass it to the spreadsheet as the input values. I'd like to keep that part of the code externally, in a version control system like Git. One additional note is that the spreadsheet uses the Solver Excel plugin.
Any help how to do that would be very appreciated.
Thanks,
Michal
To manipulate an Excel spreadsheet using Ruby, you may want to use win32ole
Here's a sample script:
data = [["Hello", "World"]]
# Require the WIN32OLE library
require 'win32ole'
# Create an instance of the Excel application object
xl = WIN32OLE.new('Excel.Application')
# Make Excel visible
xl.Visible = 1
# Add a new Workbook object
wb = xl.Workbooks.Add
# Get the first Worksheet
ws = wb.Worksheets(1)
# Set the name of the worksheet tab
ws.Name = 'Sample Worksheet'
# For each row in the data set
data.each_with_index do |row, r|
# For each field in the row
row.each_with_index do |field, c|
# Write the data to the Worksheet
ws.Cells(r+1, c+1).Value = field.to_s
end
end
# Save the workbook
wb.SaveAs('workbook.xls')
# Close the workbook
wb.Close
# Quit Excel
xl.Quit
To work out more complicated code, just record a macro of what you want to do, and then look at the code of your macro, and convert it from VB into Ruby.

Resources