Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Header rows #44

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## 2.6.0 (2024-07-10)

- Move to [ZipKit gem](http://rubygems.org/gems/zip_kit); equivalent of https://github.com/felixbuenemann/xlsxtream/pull/57/files

## 2.5.0 (2021-06-28)

- New `:add_header_row` method in Worksheet, which outputs as a row as bold text, intended for header rows

## 2.4.0 (2020-06-27)

- Allow writing worksheets without a block using add\_worksheet (#42, #45)
Expand All @@ -23,11 +31,11 @@
## 2.0.1 (2018-03-11)

- Rescue gracefully from invalid dates with auto-format (#22)
- Remove unused ZipTricksFibers IO wrapper (#24)
- Remove unused ZipKitFibers IO wrapper (#24)

## 2.0.0 (2017-10-31)

- Replace RubyZip with ZipTricks as default compressor (#16)
- Replace RubyZip with ZipKit as default compressor (#16)
- Drop support for Ruby < 2.1.0 (required for zip\_tricks gem)
- Deprecate :io\_wrapper option, you can now pass wrapper instances (#20)

Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ xlsx.write_worksheet 'AppendixSheet' do |sheet|
sheet.add_row [Time.now, 'Time-machine']
end

# Output the first row as a header line using bold text
xls.write_worksheet 'Sheet1' do |sheet|
sheet.add_header_row ['headers', 'in', 'bold']
sheet << ['first', 'normal', 'row']
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
Expand Down
13 changes: 13 additions & 0 deletions lib/xlsxtream/header_row.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

module Xlsxtream
class HeaderRow < Row
def initialize(row, rownum, options = {})
super

@normal_style = ' s="3"'
@date_style = ' s="4"'
@time_style = ' s="5"'
end
end
end
45 changes: 45 additions & 0 deletions lib/xlsxtream/io/zip_kit.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# frozen_string_literal: true
require "zip_kit"

module Xlsxtream
module IO
class ZipKit
BUFFER_SIZE = 64 * 1024

def initialize(body)
@streamer = ::ZipKit::Streamer.new(body)
@wf = nil
@buffer = String.new
end

def <<(data)
@buffer << data
flush_buffer if @buffer.size >= BUFFER_SIZE
self
end

def add_file(path)
flush_file
@wf = @streamer.write_deflated_file(path)
end

def close
flush_file
@streamer.close
end

private

def flush_buffer
@wf << @buffer
@buffer.clear
end

def flush_file
return unless @wf
flush_buffer if @buffer.size > 0
@wf.close
end
end
end
end
6 changes: 3 additions & 3 deletions lib/xlsxtream/io/zip_tricks.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# frozen_string_literal: true
require "zip_tricks"
require "zip_kit"

module Xlsxtream
module IO
class ZipTricks
class ZipKit
BUFFER_SIZE = 64 * 1024

def initialize(body)
@streamer = ::ZipTricks::Streamer.new(body)
@streamer = ::ZipKit::Streamer.new(body)
@wf = nil
@buffer = String.new
end
Expand Down
21 changes: 11 additions & 10 deletions lib/xlsxtream/row.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@ class Row
TRUE_STRING = 'true'.freeze
FALSE_STRING = 'false'.freeze

DATE_STYLE = 1
TIME_STYLE = 2

def initialize(row, rownum, options = {})
@row = row
@rownum = rownum
@sst = options[:sst]
@auto_format = options[:auto_format]

@normal_style = ''
@date_style = ' s="1"'
@time_style = ' s="2"'
end

def to_xml
Expand All @@ -40,25 +41,25 @@ def to_xml

case value
when Numeric
xml << %Q{<c r="#{cid}" t="n"><v>#{value}</v></c>}
xml << %Q{<c r="#{cid}"#{@normal_style} t="n"><v>#{value}</v></c>}
when TrueClass, FalseClass
xml << %Q{<c r="#{cid}" t="b"><v>#{value ? 1 : 0}</v></c>}
xml << %Q{<c r="#{cid}"#{@normal_style} t="b"><v>#{value ? 1 : 0}</v></c>}
when Time
xml << %Q{<c r="#{cid}" s="#{TIME_STYLE}"><v>#{time_to_oa_date(value)}</v></c>}
xml << %Q{<c r="#{cid}"#{@time_style}><v>#{time_to_oa_date(value)}</v></c>}
when DateTime
xml << %Q{<c r="#{cid}" s="#{TIME_STYLE}"><v>#{datetime_to_oa_date(value)}</v></c>}
xml << %Q{<c r="#{cid}"#{@time_style}><v>#{datetime_to_oa_date(value)}</v></c>}
when Date
xml << %Q{<c r="#{cid}" s="#{DATE_STYLE}"><v>#{date_to_oa_date(value)}</v></c>}
xml << %Q{<c r="#{cid}"#{@date_style}><v>#{date_to_oa_date(value)}</v></c>}
else
value = value.to_s

unless value.empty? # no xml output for for empty strings
value = value.encode(ENCODING) if value.encoding != ENCODING

if @sst
xml << %Q{<c r="#{cid}" t="s"><v>#{@sst[value]}</v></c>}
xml << %Q{<c r="#{cid}"#{@normal_style} t="s"><v>#{@sst[value]}</v></c>}
else
xml << %Q{<c r="#{cid}" t="inlineStr"><is><t>#{XML.escape_value(value)}</t></is></c>}
xml << %Q{<c r="#{cid}"#{@normal_style} t="inlineStr"><is><t>#{XML.escape_value(value)}</t></is></c>}
end
end
end
Expand Down
25 changes: 20 additions & 5 deletions lib/xlsxtream/workbook.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
require "xlsxtream/xml"
require "xlsxtream/shared_string_table"
require "xlsxtream/worksheet"
require "xlsxtream/io/zip_tricks"
require "xlsxtream/io/zip_kit"

module Xlsxtream
class Workbook
Expand Down Expand Up @@ -46,13 +46,13 @@ def initialize(output, options = {})
end
if output.is_a?(String) || !output.respond_to?(:<<)
@file = File.open(output, 'wb')
@io = IO::ZipTricks.new(@file)
@io = IO::ZipKit.new(@file)
elsif output.respond_to? :add_file
@file = nil
@io = output
else
@file = nil
@io = IO::ZipTricks.new(output)
@io = IO::ZipKit.new(output)
end
@sst = SharedStringTable.new
@worksheets = []
Expand Down Expand Up @@ -162,12 +162,18 @@ def write_styles
<numFmt numFmtId="164" formatCode="yyyy\\-mm\\-dd"/>
<numFmt numFmtId="165" formatCode="yyyy\\-mm\\-dd hh:mm:ss"/>
</numFmts>
<fonts count="1">
<fonts count="2">
<font>
<sz val="#{XML.escape_attr font_size}"/>
<name val="#{XML.escape_attr font_name}"/>
<family val="#{font_family_id}"/>
</font>
<font>
<b val="1"/>
<sz val="#{XML.escape_attr font_size}"/>
<name val="#{XML.escape_attr font_name}"/>
<family val="#{font_family_id}"/>
</font>
</fonts>
<fills count="2">
<fill>
Expand All @@ -183,10 +189,19 @@ def write_styles
<cellStyleXfs count="1">
<xf numFmtId="0" fontId="0" fillId="0" borderId="0"/>
</cellStyleXfs>
<cellXfs count="3">
<cellXfs count="6">
<xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0"/>
<xf numFmtId="164" fontId="0" fillId="0" borderId="0" xfId="0" applyNumberFormat="1"/>
<xf numFmtId="165" fontId="0" fillId="0" borderId="0" xfId="0" applyNumberFormat="1"/>
<xf numFmtId="0" fontId="1" fillId="0" borderId="0" xfId="0" applyAlignment="1">
<alignment vertical="center"/>
</xf>
<xf numFmtId="164" fontId="1" fillId="0" borderId="0" xfId="0" applyAlignment="1" applyNumberFormat="1">
<alignment vertical="center"/>
</xf>
<xf numFmtId="165" fontId="1" fillId="0" borderId="0" xfId="0" applyAlignment="1" applyNumberFormat="1">
<alignment vertical="center"/>
</xf>
</cellXfs>
<cellStyles count="1">
<cellStyle name="Normal" xfId="0" builtinId="0"/>
Expand Down
6 changes: 6 additions & 0 deletions lib/xlsxtream/worksheet.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true
require "xlsxtream/xml"
require "xlsxtream/row"
require "xlsxtream/header_row"

module Xlsxtream
class Worksheet
Expand All @@ -19,6 +20,11 @@ def <<(row)
end
alias_method :add_row, :<<

def add_header_row(row)
@io << HeaderRow.new(row, @rownum, @options).to_xml
@rownum += 1
end

def close
write_footer
@closed = true
Expand Down
Loading