Giter Site home page Giter Site logo

xlsxtream's Introduction

Xlsxtream

Gem Version Build Status

Xlsxtream is a streaming writer for XLSX spreadsheets. It supports multiple worksheets and optional string deduplication via a shared string table (SST). Its purpose is to replace CSV for large exports, because using CSV in Excel is very buggy and error prone. It's very efficient and can quickly write millions of rows with low memory usage.

Xlsxtream does not support formatting, charts, comments and a myriad of other OOXML features. If you are looking for a fully featured solution take a look at caxslx.

Xlsxtream supports writing to files or IO-like objects, data is flushed as the ZIP compressor sees fit.

Installation

Add this line to your application's Gemfile:

gem 'xlsxtream'

And then execute:

$ bundle

Or install it yourself as:

$ gem install xlsxtream

Usage

# Creates a new workbook and closes it at the end of the block
Xlsxtream::Workbook.open('my_data.xlsx') do |xlsx|
  xlsx.write_worksheet 'Sheet1' do |sheet|
    # Boolean, Date, Time, DateTime and Numeric are properly mapped
    sheet << [true, Date.today, 'hello', 'world', 42, 3.14159265359, 42**13]
  end
end

io = StringIO.new
xlsx = Xlsxtream::Workbook.new(io)

# Number of columns doesn't have to match
xlsx.write_worksheet 'Sheet1' do |sheet|
  sheet << ['first', 'row']
  sheet << ['second', 'row', 'with', 'more colums']
end

# Write multiple worksheets with custom names
xlsx.write_worksheet 'AppendixSheet' do |sheet|
  sheet.add_row ['Timestamp', 'Comment']
  sheet.add_row [Time.now, 'Good times']
  sheet.add_row [Time.now, 'Time-machine']
end

# If you have highly repetitive data, you can enable Shared String Tables (SST)
# for the workbook or a single worksheet. The SST has to be kept in memory,
# so do not use it if you have a huge amount of rows or a little duplication
# of content across cells. A single SST is used for the whole workbook.
xlsx.write_worksheet(name: 'SheetWithSST', use_shared_strings: true) do |sheet|
  sheet << ['the', 'same', 'old', 'story']
  sheet << ['the', 'old', 'same', 'story']
  sheet << ['old', 'the', 'same', 'story']
end

# Strings in numeric or date/time format can be auto-detected and formatted
# appropriately. This is a convenient way to avoid an Excel-warning about
# "Number stored as text". Dates and times must be in the ISO-8601 format and
# numeric values must contain only numbers and an optional decimal separator.
# The strings true and false are detected as boolean values.
xlsx.write_worksheet(name: 'SheetWithAutoFormat', auto_format: true) do |sheet|
  # these two rows will be identical in the xlsx-output
  sheet << [true, 11.85, DateTime.parse('2050-01-01T12:00'), Date.parse('1984-01-01')]
  sheet << ['true', '11.85', '2050-01-01T12:00', '1984-01-01']
end

# You can also create worksheet without a block, using the `add_worksheet` method.
# It can be only used sequentially, so remember to manually close the worksheet
# when you are done (before opening a new one).
worksheet = xls.add_worksheet(name: 'SheetWithoutBlock')
worksheet << ['some', 'data']
worksheet.close

# Writes metadata and ZIP archive central directory
xlsx.close
# Close IO object
io.close

# Changing the default font from Calibri, 12pt, Swiss
Xlsxtream::Workbook.new(io, font: {
  name: 'Times New Roman',
  size: 10, # size in pt
  family: 'Roman' # Swiss, Modern, Script, Decorative
})

# Specifying column widths in pixels or characters; 3 column example;
# "pixel" widths appear to be *relative* to an assumed 11pt Calibri
# font, so if selecting a different font or size (see above), do not
# adjust widths to match. Calculate pixel widths for 11pt Calibri.
Xlsxtream::Workbook.new(io, columns: [
  { width_pixels: 33 },
  { width_chars: 7 },
  { width_chars: 24 }
])
# The :columns option can also be given to write_worksheet, so it's
# possible to have multiple worksheets with different column widths.

Compatibility

The current version of Xlsxtream requires at least Ruby 2.1.0.

If you are using an older Ruby version you can use the following in your Gemfile:

gem 'xlsxtream', '< 2'
  • The last version with support for Ruby 1.9.1 is 1.2.0.
  • The last version with support for Ruby 1.9.2 is 1.3.2.

Upgrading

If you are upgrading from a version earlier than 2.x and are using the undocumented :io_wrapper option you need to update your code:

# Pre 2.x code with :io_wrapper option
Xlsxtream::Workbook.new(io, io_wrapper: MyCustomIOWrapper)
# New code with IO wrapper instance
io_wrapper = MyCustomIOWrapper.new(io)
Xlsxtream::Workbook.new(io_wrapper)

Every IO-like object that responds to :add_file is treated as an IO wrapper.

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake test to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/felixbuenemann/xlsxtream.

License

The gem is available as open source under the terms of the MIT License.

xlsxtream's People

Contributors

andre-meier avatar brettwgreen avatar felixbuenemann avatar julik avatar kukicola avatar opencoderx avatar pond avatar sandstrom avatar vgonda avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

xlsxtream's Issues

Allow worksheet name as an option

It would be great to support specifying the sheet name as an option instead of an argument to #write_worksheet, so we could use:

xlsx.write_worksheet(name: 'Sheet1', use_shared_strings: true) do |sheet|
end

Instead of:

xlsx.write_worksheet('Sheet1', use_shared_strings: true) do |sheet|
end

Rails stream downloading xlsx files builded on the fly

I have a Rails app. Users have to be able to download large xlsx files. I'm trying to use xlsxtream gem with ActionController::Live.

Here is my controller's action:

def index
 response.headers.delete('Content-Length')                                                                       
 response.headers['Content-Type'] ||= 'application/application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
 response.headers['Content-Disposition'] = "attachment; filename=full.xlsx"                 
 response.headers['X-Accel-Buffering'] = 'no'                                                                    
 response.headers['Cache-Control'] ||= 'no-cache'                                                                
                                                                                                                        
 st = MyIO.new(response.stream)                                                                                  
 begin                                                                                                           
   xlsx = Xlsxtream::Workbook.new(st)                                                                            
   1_000.times do |i|                                                                            
      xlsx.write_worksheet 'Sheet1' do |sheet|                                                                    
        sheet << [i, SecureRandom.hex(8)]                                                                         
      end                                                                                                         
    end                                                                                                           
    xlsx.close                                                                                                    
  ensure                                                                                                          
    st.close                                                                                                      
  end                                                                                                             
end

Here is MyIO implementation:

class MyIO < StringIO                                                                                                   
  def initialize(st)                                                                                                    
    @st = st                                                                                                            
    super()                                                                                                             
  end                                                                                                                   
                                                                                                                        
  def <<(data)                                                                                                          
    @st.write(data)                                                                                                     
  end                                                                                                                   
                                                                                                                        
  def close                                                                                                             
    @st.close                                                                                                           
  end                                                                                                                   
end 

I get an error:

Zip::Error (local header size changed (0 -> 54)):              
   /usr/local/bundle/gems/rubyzip-1.2.1/lib/zip/entry.rb:137:in `verify_local_header_size!'
   /usr/local/bundle/gems/rubyzip-1.2.1/lib/zip/entry.rb:274:in `write_local_entry'
   /usr/local/bundle/gems/rubyzip-1.2.1/lib/zip/output_stream.rb:161:in `block in update_local_headers'
   /usr/local/bundle/gems/rubyzip-1.2.1/lib/zip/entry_set.rb:38:in `block in each'
   /usr/local/bundle/gems/rubyzip-1.2.1/lib/zip/entry_set.rb:37:in `each'
   /usr/local/bundle/gems/rubyzip-1.2.1/lib/zip/entry_set.rb:37:in `each'
   /usr/local/bundle/gems/rubyzip-1.2.1/lib/zip/output_stream.rb:159:in `update_local_headers'
   /usr/local/bundle/gems/rubyzip-1.2.1/lib/zip/output_stream.rb:80:in `close_buffer'
   /usr/local/bundle/gems/xlsxtream-1.1.0/lib/xlsxtream/io/rubyzip.rb:21:in `close'
   /usr/local/bundle/gems/xlsxtream-1.1.0/lib/xlsxtream/workbook.rb:66:in `close'

File can be downloaded but it's corrupted. Is it possible to use this gem this way?

Does it support data_validation and formulas?

Hi, thanks for creating this gem.

Does your gem support data validation and formula in cells?
Sorry but I dind't find it in the Docs.

ps.: By data_validation I mean this: https://github.com/randym/axlsx/blob/master/examples/data_validation.rb

Cheers

question: Is there a upper limit to the amount of data you can put in a cell?

Hello,
Really appreciate this project as it has allowed us to stream xlsx content much easier.

I apologize for asking here, but I've tried to search this in google with no help. Is there a max cap on the amount of data you can put in a cell? (specifically String)

I've noticed that for larger strings, the content seems to get cutoff. Was wondering if this is a general excel issue, or a limitation of this project.

Thank you very much!

How to change font size, font weight

Hi,
Is there any option to set the font size, font weight like this?
I have used it, very simple to use but my generated xlsx fonts are larger and bold automatically. which needs to be changed.
Here is my code

      tmp_file = Tempfile.new(["template", ".xlsx"])
      # Creates a new workbook and closes it at the end of the block
      Xlsxtream::Workbook.open(tmp_file.path) do |xlsx|
        xlsx.write_worksheet('Sheet1', :auto_format => true, :use_shared_strings => true) do |sheet|
          sheet << accepted_columns
          JobTemplate.all.each do |job_template|
            sheet << job_template.attributes.except(rejected_columns.map {|str| str}.join(',')).values_at(*accepted_columns)
          end
        end
      end

Please let me know if it can be done.
Thanks

Money type

Hi,

I would like to generate an xlsx file in which one of the columns is a currency type. My objects are Money (https://github.com/RubyMoney/money) instances.

I am currently this:

Money.new(1003450).format(thousands_separator: '', symbol: false, decimal_mark: '.')
=> "10034.50"

The excel is generated with a column of type numeric.

I was wondering if you could add support of currency format.

Thanks.

Encoding::UndefinedConversionError: "\xEF" from ASCII-8BIT to UTF-8

I am running into the following error when trying to use the gem. I suspect its because I am using data with wrong encoding. I am not sure how to solve it though and any ideas are welcome. My code looks like this:

Xlsxtream::Workbook.open(filename) do |xlsx|
      xlsx.write_worksheet WORKSHEET_NAME do |sheet|
        sheet << headings
      end
end

headings here is an array of values. Do the values have to be in a particular format?

I tried the example provided:

Xlsxtream::Workbook.open(filename) do |xlsx|
      xlsx.write_worksheet WORKSHEET_NAME do |sheet|
        # Boolean, Date, Time, DateTime and Numeric are properly mapped
        sheet << [true, Date.today, 'hello', 'world', 42, 3.14159265359, 42**13]
      end
end

and even this is giving me Encoding::UndefinedConversionError: "\x91" from ASCII-8BIT to UTF-8. The character is different. But the same error.

Option to add empty cells

Hello again!
I had one more issue with this gem. It's a pretty strange excel formatting behavior - if a cell with an overflowing text is next to the cell which does not exist in file it allows the text to overflow.
Example:
Zrzut ekranu 2020-04-17 o 18 30 51
Adding blank cell after this one fixes the issue:
Zrzut ekranu 2020-04-17 o 18 31 28
On my fork I dealt with it by just removing condition to skip empty cells:
https://github.com/paladinsoftware/xlsxtream/pull/2/files

Maybe it would be good to introduce an option like empty_cells: which is false by default. I can create a PR if you think that it can be useful.

Corrupt file when using Tempfile IO

The following code produces a corrupt XLSX file which is missing a the ZIP end of central directory record (EOCD) so it is 22 bytes short:

io = Tempfile.new
io.binmode
Xlsxtream::Workbook.open(io) do |xlsx|
  xlsx.write_worksheet("Sheet1") { |ws| ws << ["Hello"]  }
end
io.size
=> 2140

The following code works correct:

io = File.new "foo.xlsx", "wb"
Xlsxtream::Workbook.open(io) do |xlsx|
  xlsx.write_worksheet("Sheet1") { |ws| ws << ["Hello"]  }
end
io.size
=> 2162

Which is pretty weird, because it should exercise the same code paths.

Date formatting

Is there a way to export dates in XLSX without using a custom format?

Example of custom format in image below (this screenshot is from Numbers in macOS).

avoid-date-xlsx


If I understand things correctly the 1 or 2 value for the s-attribute in say <c r="E2" s="2"> determines the style, and the two styles are defined here. Is that correct?

According to this document from Microsoft they will interpret HH:MM:SS, YYYY-MM-DD and YYYY-MM-DDTHH:MM:SS as times/dates automatically.

Would you be willing to add configuration/options to toggle this (i.e. go with plain, correctly formatted date/time string and let Excel infer)?

Let me know if I've misunderstood things, perhaps there are considerations here that I'm not aware of. I'll admit I don't know too much about the XLSX-format.

Control characters break xlsx generation

Hi Felix, thank you for this gem, it works well. I found out that having control characters in my model's attributes (e.g. varchars with dirty user input etc.) will break the xlsx generation. The xlsx file will "end" at the first control character.

I was able to work around it by using .strip on all strings I add to the sheet. Maybe there is a more elegant solution?

Writing to an existing file

When writing to an existing file, the file is closed after calling xlsx.close, so reading it afterwards isn't possible. There are workarounds (see below), but it would be nice if this wasn't needed.

It seems like it's the zip-library that closes the input_io (the argument to Workbook.new), so it may be outside the scope of this lib.

Let me know what you think!

# does not work
def generate_xlsx(original_file)
  xlsx = Xlsxtream::Workbook.new(original_file)

  xlsx.write_worksheet 'Sheet1' do |sheet|
    sheet << ['cat', 'dog', Time.now]
  end

  xlsx.close

  original_file << path.read
  original_file
end

def other_method
  output = generate_xlsx(my_file)
  upload_to_s3(output.read) # raises `IOError: closed stream`
end

# works
def generate_xlsx(original_file)
  path = Rails.root.join('tmp', "xlsx-ephemeral-#{Time.now.to_i}-#{Random.rand}")

  intermediary_file = File.new(path, 'wb')

  xlsx = Xlsxtream::Workbook.new(intermediary_file)

  xlsx.write_worksheet 'Sheet1' do |sheet|
    sheet << ['cat', 'dog', Time.now]
  end

  xlsx.close

  original_file << path.read
  original_file
ensure
  FileUtils.rm path
end

def other_method
  output = generate_xlsx(my_file)
  upload_to_s3(output.read)
end

I know there is an io_wrapper where one could intercept and ignore the closing, but it would be nice if there was an easier way.

Storing numeric strings as numbers

I've noticed that Excel shows a warning if numeric strings (strings with only numeric characters) are present in a spreadsheet.

screen shot 2017-09-07 at 16 56 51

I think the fix is fairly straightforward. Basically something like this (I haven't checked that this code works, just to illustrate the idea)

if value.is_a?(String) && value =~ /\A[\d\.]+/z/
  # add as a value
else
  # current handling of strings…
end

Would you be willing to add functionality along these lines? Either by default or behind an option (opt-in or opt-out).

How to Configure xlsxtream Properly

Hi, I want to ask how to configure xlsxtream properly so that user can download the .xlsx file.

Firstly, what I have done is create code as below to link to export path:

<div class="float-left">
   <%= link_to "Export All", export_path, class: "btn btn-primary", target: "_blank" %>
</div>

Above code is located in my index.html.erb file.

Then, below is the code in my dashboard_controller.erb file for the export function:

def export
  @logging ||= Logging.new
  @qsos = current_user.logging.qsos

  xlsx = Xlsxtream::Workbook.new("#{current_user.callsign}.xlsx", font: { name: 'Arial', size: 11 })
  xlsx.write_worksheet 'Sheet1' do |sheet|
    sheet << ['DATE', 'TIME', 'CQ STATION', 'CALLSIGN', 'BAND', 'FREQ', 'MODE', 'RECV', 'SENT']
	  
    @qsos.each do |qso|
      sheet << [qso.time.strftime("%Y-%m-%d"), qso.time.strftime("%H%M"), qso.logging.user.callsign.upcase, qso.callsign, qso.band, "#{(qso.frequency.to_f).round(3)} MHz", qso.mode, qso.rst_rcvd, qso.rst_sent]
    end 
  end
  xlsx.close
	
end

Yet, when I click the "Export All" button, it return below errors:

Sending event b88c60665d86448c802fc99aed5f4005 to Sentry
Unable to record event with remote Sentry server (Raven::Error - SSL_connect ret
urned=1 errno=0 state=error: certificate verify failed):
C:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/sentry-raven-2.7.4/lib/rave
n/transports/http.rb:34:in `rescue in send_event'
C:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/sentry-raven-2.7.4/lib/rave
n/transports/http.rb:17:in `send_event'
C:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/sentry-raven-2.7.4/lib/rave
n/client.rb:37:in `send_event'
C:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/sentry-raven-2.7.4/lib/rave
n/instance.rb:81:in `send_event'
C:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/sentry-raven-2.7.4/lib/rave
n/instance.rb:126:in `capture_type'
C:/RailsInstaller/Ruby2.3.0/lib/ruby/2.3.0/forwardable.rb:189:in `capture_type'
C:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/sentry-raven-2.7.4/lib/rave
n/integrations/rack.rb:28:in `capture_type'
C:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/sentry-raven-2.7.4/lib/rave
n/integrations/rails/overrides/debug_exceptions_catcher.rb:8:in `render_exceptio
n'
C:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/actionpack-5.2.1/lib/action
_dispatch/middleware/debug_exceptions.rb:71:in `rescue in call'
C:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/actionpack-5.2.1/lib/action
_dispatch/middleware/debug_exceptions.rb:60:in `call'
C:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/newrelic_rpm-5.3.0.346/lib/
new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
Failed to submit event: ActionController::UnknownFormat: DashboardController#exp
ort is missing a template for this request format and variant.

request.formats: ["text/html"]
request.variant: []

NOTE! For XHR/Ajax or API requests, this action would normally respond with 204
No Content: an empty white screen. Since you're loading it in a web browser, we
assume that you expected to actually render a template, not nothing, so we're sh
owing an error to be extra-clear. If you expect 204 No Content, carry on. That's
 what you'll get from an XHR or API request. Give it a shot.

ActionController::UnknownFormat (DashboardController#export is missing a templat
e for this request format and variant.

request.formats: ["text/html"]
request.variant: []

NOTE! For XHR/Ajax or API requests, this action would normally respond with 204
No Content: an empty white screen. Since you're loading it in a web browser, we
assume that you expected to actually render a template, not nothing, so we're sh
owing an error to be extra-clear. If you expect 204 No Content, carry on. That's
 what you'll get from an XHR or API request. Give it a shot.):

actionpack (5.2.1) lib/action_controller/metal/implicit_render.rb:55:in `default
_render'
actionpack (5.2.1) lib/action_controller/metal/basic_implicit_render.rb:6:in `bl
ock in send_action'
actionpack (5.2.1) lib/action_controller/metal/basic_implicit_render.rb:6:in `ta
p'
actionpack (5.2.1) lib/action_controller/metal/basic_implicit_render.rb:6:in `se
nd_action'
actionpack (5.2.1) lib/abstract_controller/base.rb:194:in `process_action'
actionpack (5.2.1) lib/action_controller/metal/rendering.rb:30:in `process_actio
n'
actionpack (5.2.1) lib/abstract_controller/callbacks.rb:42:in `block in process_
action'
activesupport (5.2.1) lib/active_support/callbacks.rb:109:in `block in run_callb
acks'
sentry-raven (2.7.4) lib/raven/integrations/rails/controller_transaction.rb:7:in
 `block in included'
activesupport (5.2.1) lib/active_support/callbacks.rb:118:in `instance_exec'
activesupport (5.2.1) lib/active_support/callbacks.rb:118:in `block in run_callb
acks'
activesupport (5.2.1) lib/active_support/callbacks.rb:136:in `run_callbacks'
actionpack (5.2.1) lib/abstract_controller/callbacks.rb:41:in `process_action'
actionpack (5.2.1) lib/action_controller/metal/rescue.rb:22:in `process_action'
actionpack (5.2.1) lib/action_controller/metal/instrumentation.rb:34:in `block i
n process_action'
activesupport (5.2.1) lib/active_support/notifications.rb:168:in `block in instr
ument'
activesupport (5.2.1) lib/active_support/notifications/instrumenter.rb:23:in `in
strument'
activesupport (5.2.1) lib/active_support/notifications.rb:168:in `instrument'
actionpack (5.2.1) lib/action_controller/metal/instrumentation.rb:32:in `process
_action'
actionpack (5.2.1) lib/action_controller/metal/params_wrapper.rb:256:in `process
_action'
activerecord (5.2.1) lib/active_record/railties/controller_runtime.rb:24:in `pro
cess_action'
actionpack (5.2.1) lib/abstract_controller/base.rb:134:in `process'
actionview (5.2.1) lib/action_view/rendering.rb:32:in `process'
actionpack (5.2.1) lib/action_controller/metal.rb:191:in `dispatch'
actionpack (5.2.1) lib/action_controller/metal.rb:252:in `dispatch'
actionpack (5.2.1) lib/action_dispatch/routing/route_set.rb:52:in `dispatch'
actionpack (5.2.1) lib/action_dispatch/routing/route_set.rb:34:in `serve'
actionpack (5.2.1) lib/action_dispatch/journey/router.rb:52:in `block in serve'
actionpack (5.2.1) lib/action_dispatch/journey/router.rb:35:in `each'
actionpack (5.2.1) lib/action_dispatch/journey/router.rb:35:in `serve'
actionpack (5.2.1) lib/action_dispatch/routing/route_set.rb:840:in `call'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
scout_apm (2.4.17) lib/scout_apm/instant/middleware.rb:53:in `call'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
scout_apm (2.4.17) lib/scout_apm/middleware.rb:17:in `call'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
newrelic_rpm (5.3.0.346) lib/new_relic/rack/agent_hooks.rb:30:in `traced_call'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
newrelic_rpm (5.3.0.346) lib/new_relic/rack/browser_monitoring.rb:32:in `traced_
call'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
warden (1.2.7) lib/warden/manager.rb:36:in `block in call'
warden (1.2.7) lib/warden/manager.rb:35:in `catch'
warden (1.2.7) lib/warden/manager.rb:35:in `call'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
rack (2.0.5) lib/rack/tempfile_reaper.rb:15:in `call'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
rack (2.0.5) lib/rack/etag.rb:25:in `call'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
rack (2.0.5) lib/rack/conditional_get.rb:25:in `call'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
rack (2.0.5) lib/rack/head.rb:12:in `call'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
actionpack (5.2.1) lib/action_dispatch/http/content_security_policy.rb:18:in `ca
ll'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
rack (2.0.5) lib/rack/session/abstract/id.rb:232:in `context'
rack (2.0.5) lib/rack/session/abstract/id.rb:226:in `call'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
actionpack (5.2.1) lib/action_dispatch/middleware/cookies.rb:670:in `call'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
activerecord (5.2.1) lib/active_record/migration.rb:559:in `call'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
actionpack (5.2.1) lib/action_dispatch/middleware/callbacks.rb:28:in `block in c
all'
activesupport (5.2.1) lib/active_support/callbacks.rb:98:in `run_callbacks'
actionpack (5.2.1) lib/action_dispatch/middleware/callbacks.rb:26:in `call'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
actionpack (5.2.1) lib/action_dispatch/middleware/executor.rb:14:in `call'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
actionpack (5.2.1) lib/action_dispatch/middleware/debug_exceptions.rb:61:in `cal
l'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
web-console (3.6.2) lib/web_console/middleware.rb:135:in `call_app'
web-console (3.6.2) lib/web_console/middleware.rb:30:in `block in call'
web-console (3.6.2) lib/web_console/middleware.rb:20:in `catch'
web-console (3.6.2) lib/web_console/middleware.rb:20:in `call'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
actionpack (5.2.1) lib/action_dispatch/middleware/show_exceptions.rb:33:in `call
'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
railties (5.2.1) lib/rails/rack/logger.rb:38:in `call_app'
railties (5.2.1) lib/rails/rack/logger.rb:26:in `block in call'
activesupport (5.2.1) lib/active_support/tagged_logging.rb:71:in `block in tagge
d'
activesupport (5.2.1) lib/active_support/tagged_logging.rb:28:in `tagged'
activesupport (5.2.1) lib/active_support/tagged_logging.rb:71:in `tagged'
railties (5.2.1) lib/rails/rack/logger.rb:26:in `call'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
sprockets-rails (3.2.1) lib/sprockets/rails/quiet_assets.rb:13:in `call'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
actionpack (5.2.1) lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
actionpack (5.2.1) lib/action_dispatch/middleware/request_id.rb:27:in `call'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
rack (2.0.5) lib/rack/method_override.rb:22:in `call'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
rack (2.0.5) lib/rack/runtime.rb:22:in `call'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
activesupport (5.2.1) lib/active_support/cache/strategy/local_cache_middleware.r
b:29:in `call'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
actionpack (5.2.1) lib/action_dispatch/middleware/executor.rb:14:in `call'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
actionpack (5.2.1) lib/action_dispatch/middleware/static.rb:127:in `call'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
rack (2.0.5) lib/rack/sendfile.rb:111:in `call'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
sentry-raven (2.7.4) lib/raven/integrations/rack.rb:51:in `call'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
railties (5.2.1) lib/rails/engine.rb:524:in `call'
newrelic_rpm (5.3.0.346) lib/new_relic/agent/instrumentation/middleware_tracing.
rb:92:in `call'
puma (3.12.0) lib/puma/configuration.rb:225:in `call'
puma (3.12.0) lib/puma/server.rb:658:in `handle_request'
puma (3.12.0) lib/puma/server.rb:472:in `process_client'
puma (3.12.0) lib/puma/server.rb:332:in `block in run'
puma (3.12.0) lib/puma/thread_pool.rb:133:in `block in spawn_thread'

However, although there is errors, the .xlsx file still being successfully created. Yet it is in local directory. Why?

image 3
What I do wrong? Thank you.

Date cell leads to cell type 'Custom format'

Hi,
what i'm missing is to set a cell's value to a Date/DateTime and define a custom format which leads to

  • cell category 'Date' (and not 'Custom' which is the case at the moment)
  • the date is shown in the defined format

Until now i used rubyXL, which allowed this approach for a Date cell:

c = workbook[0].add_cell(0,0)
c.set_number_format('dd.mm.yyyy')
c.change_contents(Date.today)

Is that possible here too?
Thanks a lot.

Additional quotation symbol is added to cells with text that is number

I have tried couple of ruby libraries (this one and https://github.com/Paxa/fast_excel ) and when I am just trying to create cell with text that has numeric value:

Xlsxtream::Workbook.open('my_data.xlsx') do |xlsx|
  xlsx.write_worksheet 'Sheet1' do |sheet|
    # Boolean, Date, Time, DateTime and Numeric are properly mapped
    sheet << ["2019"]
  end
end

when I open my_data.xlsx then 2019 cell is shown with '2019 value, not just 2019. Is there a way to change that? (didn't have a chance to use Excel for now, only used LibreOffice 5 and 6)

zip_tricks update

Hi there. I see that there is newer version of zip_tricks (newest 5.0.0, installed 4.8.0).
Could you please update dependencies. Thank you

Allow setting number format

Hi,

It would be nice if the number format could be set to something like #,##0 for the whole spreadsheet/book

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.