I'm trying to do the same as that question
caxlsx / axlsx Pivot Table on separate sheet
but in the same sheet.
When i do:
summary_sheet.add_pivot_table 'A91:E140', 'A53:O68' do |pivot_table|
pivot_table.rows = ['Activity']
pivot_table.columns = ['Project']
end
And then go to inspect what happened, i find that the source data on the generated file have $'DPCache_Data Sheet'.$A$1:$O$16 while i been waiting $Summary.$A53$O68
And yes, don't return what i want, giving pivot_table.data_sheet to itself with something like
pivot_table.data_sheet = summary_sheet
or this
pivot_table.data_sheet = pivot_table
not works anyway.
UPDATE FOR #kevinluo201
Your reply do that
Thank you but not solves.
My file starts with
wb = xlsx_package.workbook
Doing with
wb = Axlsx::Package.new.workbook
Return an empty file
:add_pivot_table can be used as add_pivot_table(:pivot_table_position, :data_source)
If you want to create a worksheet called "Summary" and insert data and then create a pivot table, here my version I modified a little bit from the https://github.com/caxlsx/caxlsx/blob/master/examples/pivot_table_example.md
require 'caxlsx'
p = Axlsx::Package.new
wb = p.workbook
wb.add_worksheet(name: 'Summary') do |sheet|
sheet.add_row ['Activity', 'Project']
# Generate some data here in the range of 'A53:O68'
# ...
# ...
# ...
# within the same worksheet, call :add_pivot_table
sheet.add_pivot_table '$G$5', 'A53:O68', sort_on_headers: ['Activities'] do |pivot_table|
pivot_table.rows = ['Activities]
pivot_table.columns = ['Project']
end
end
p.serialize 'pivot_table_example.xlsx'
Open the generated pivot_table_example.xlsx and go to G5 cell, you'll see the pivot table there with the data source from 'A53:O68'.
Related
I am currently trying to work this in my website , https://github.com/gimite/google-drive-ruby
because i want to store some submitted information to my google sheets , everytime someone submits the form.
After implementing "on behalf of you" method to my rails, i am able to save these information to my google sheets. However, i have a serious issue where , if there are more than 1 people submitting the form the same time, three things might happen
1) both forms keyed into the sheet
2) one of the form is keyed twice
3) (if 3 form run at same time) one entry goes missing.
this is my ruby definition in my controller which will trigger when the user hits the submit button.
def save_googlesheet
session = GoogleDrive::Session.from_config("config.json")
ws = session.spreadsheet_by_key("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx").worksheets[0]
ws1 = session.spreadsheet_by_key("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx").worksheets[1]
# get row value and update row sheet val
row = p ws1[1, 2].to_i + 1
ws1[1,2] = row;
ws1.save
column = 1;
ws[row, column+1] = #some_form.name_first
ws[row, column+2] = #some_form.name_last
ws[row, column+3] = #some_form.job_title
ws[row, column+4] = #some_form.zip
ws[row, column+5] = #some_form.addr1
ws[row, column+6] = #some_form.addr2
ws[row, column+6] = #some_form.addr3
ws[row, column+7] = #some_form.mail
ws[row, column+8] = #some_form.tel
ws.save
end
def get_row_googlesheet
session = GoogleDrive::Session.from_config("config.json")
end
Just to note, i have 2 spreadsheet. the second sheet keeps the row number. I used this solution because i am not sure how to prevent 2 people from overriding the same row at the same time. And the first spreadsheet is of course the file i wish to be updating.
I would recommend to use a background job using any job library, so when the user submits a form que the job to write in to google sheet
http://tutorials.jumpstartlab.com/topics/performance/background_jobs.html
https://github.com/resque/resque
http://redistogo.com/documentation/resque
After accepting data through a form for one table, I want to process that data and use it to generate entries for another table. Essentially I will be taking the first set of data, plugging it into a formula, and then entering the result as the entry of another table. Each original set of data generates multiple rows in the other table (as the formula runs several times with one variable being incremented throughout the runs).
In short, I want to do something like this:
def show
#diagram = Diagram.find(params[:id])
#horizon = #diagram.horiz
#horizon.times do |i|
#cashflow = Cashflow.new
#flow = compute_cashflow(#diagram.investment, i)
#cashflow.flow = #flow
#cashflow.year = i
#cashflow.save
end
end
Is this possible? Thanks in advance.
EDIT
Here is the function "compute_cashflow(investment, year)":
def compute_cashflow(investment, year)
return investment+year
end
(it's meaningless right now but I want to test the idea)
I have to loop through an array and I'm not sure which row I'm going to start at since that varies:
def add_data
#sheet = #workbook.create_worksheet
responses.each do |response|
# I want something like #sheet.rows << [response.id]
end
end
I'm looking through the docs but all the examples given use a specified row index: http://spreadsheet.rubyforge.org/GUIDE_txt.html
How would I push an array of values to the next row in the file?
Just dug into the classes themselves and came up with a solution... the documentation kinda whomps:
#sheet.insert_row(#sheet.last_row_index + 1, ["hey", "cool"])
I have many documents in CSV format(about 100 different .csv files). I want to merge all of them into one .xls document. I want each CSV document to represent a worksheet in my new xls document. So my final result should be one xls workbook with 100 different worksheets which were originally .csv documents.
I'd use a scripting language such as vbs. It plays well with Excel and other MS Applications, and you can run it from either command line or double clicking on the file.
You need to add values for those two arguments or
If you do command line you can pass the srccsvfile and tgtxlsfile parameters like:
cscript nameoffile.vbs test.csv test.xls
Here is some sample code. Save as nameoffile.vbs:
srccsvfile = Wscript.Arguments(0)
tgtxlsfile = Wscript.Arguments(1)
'Create Spreadsheet
'Look for an existing Excel instance.
On Error Resume Next ' Turn on the error handling flag
Set objExcel = GetObject(,"Excel.Application")
'If not found, create a new instance.
If Err.Number = 429 Then '> 0
Set objExcel = CreateObject("Excel.Application")
End If
objExcel.Visible = false
objExcel.displayalerts=false
'Import CSV into Spreadsheet
Set objWorkbook = objExcel.Workbooks.open(srccsvfile)
Set objWorksheet1 = objWorkbook.Worksheets(1)
'Adjust width of columns
Set objRange = objWorksheet1.UsedRange
objRange.EntireColumn.Autofit()
'This code could be used to AutoFit a select number of columns
'For intColumns = 1 To 17
' objExcel.Columns(intColumns).AutoFit()
'Next
'Make Headings Bold
objExcel.Rows(1).Font.Bold = TRUE
'Freeze header row
With objExcel.ActiveWindow
.SplitColumn = 0
.SplitRow = 1
End With
objExcel.ActiveWindow.FreezePanes = True
'Add Data Filters to Heading Row
objExcel.Rows(1).AutoFilter
'set header row gray
objExcel.Rows(1).Interior.ColorIndex = 15
'-0.249977111117893
'Save Spreadsheet, 51 = Excel 2007-2010
objWorksheet1.SaveAs tgtxlsfile, 51
'Release Lock on Spreadsheet
objExcel.Quit()
Set objWorksheet1 = Nothing
Set objWorkbook = Nothing
Set ObjExcel = Nothing
I have a simple 4-column Excel spreadsheet that matches universities to their ID codes for lookup purposes. The file is pretty big (300k).
I need to come up with a way to turn this data into a populated table in my Rails app. The catch is that this is a document that is updated now and then, so it can't just be a one-time solution. Ideally, it would be some sort of ruby script that would read the file and create the entries automatically so that when we get emailed a new version, we can just update it automatically. I'm on Heroku if that matters at all.
How can I accomplish something like this?
If you can, save the spreadsheet as CSV, there's much better gems for parsing CSV files than for parsing excel spreadsheets. I found an effective way of handling this kind of problem is to make a rake task that reads the CSV file and creates all the records as appropriate.
So for example, here's how to read all the lines from a file using the old, but still effective FasterCSV gem
data = FasterCSV.read('lib/tasks/data.csv')
columns = data.remove(0)
unique_column_index = -1#The index of a column that's always unique per row in the spreadsheet
data.each do | row |
r = Record.find_or_initialize_by_unique_column(row[unique_column_index])
columns.each_with_index do | index, column_name |
r[column_name] = row[index]
end
r.save! rescue => e Rails.logger.error("Failed to save #{r.inspect}")
end
It does kinda rely on you having a unique column in the original spreadsheet to go off though.
If you put that into a rake task, you can then wire it into you're Capistrano deploy script, so it'll be run every time you deploy. the find_or_initialize should ensure you shouldn't get duplicate records.
Parsing newish Excel files isn't too much trouble using Hpricot. This will give you a two-dimensional array:
require 'hpricot'
doc = open("data.xlsx") { |f| Hpricot(f) }
rows = doc.search('row')
rows = rows[1..rows.length] # Skips the header row
rows = rows.map do |row|
columns = []
row.search('cell').each do |cell|
# Excel stores cell indexes rather than blank cells
next_index = (cell.attributes['ss:Index']) ? (cell.attributes['ss:Index'].to_i - 1) : columns.length
columns[next_index] = cell.search('data').inner_html
end
columns
end