ricardoo27-writeexcel 0.6.12.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitattributes +1 -0
- data/README.rdoc +136 -0
- data/Rakefile +52 -0
- data/VERSION +1 -0
- data/charts/chartex.rb +316 -0
- data/charts/demo1.rb +46 -0
- data/charts/demo101.bin +0 -0
- data/charts/demo2.rb +65 -0
- data/charts/demo201.bin +0 -0
- data/charts/demo3.rb +117 -0
- data/charts/demo301.bin +0 -0
- data/charts/demo4.rb +119 -0
- data/charts/demo401.bin +0 -0
- data/charts/demo5.rb +48 -0
- data/charts/demo501.bin +0 -0
- data/examples/a_simple.rb +43 -0
- data/examples/autofilter.rb +265 -0
- data/examples/bigfile.rb +30 -0
- data/examples/chart_area.rb +121 -0
- data/examples/chart_bar.rb +120 -0
- data/examples/chart_column.rb +120 -0
- data/examples/chart_line.rb +120 -0
- data/examples/chart_pie.rb +108 -0
- data/examples/chart_scatter.rb +121 -0
- data/examples/chart_stock.rb +148 -0
- data/examples/chess.rb +142 -0
- data/examples/colors.rb +129 -0
- data/examples/comments1.rb +27 -0
- data/examples/comments2.rb +352 -0
- data/examples/copyformat.rb +52 -0
- data/examples/data_validate.rb +279 -0
- data/examples/date_time.rb +87 -0
- data/examples/defined_name.rb +32 -0
- data/examples/demo.rb +124 -0
- data/examples/diag_border.rb +36 -0
- data/examples/formats.rb +490 -0
- data/examples/formula_result.rb +30 -0
- data/examples/header.rb +137 -0
- data/examples/hide_sheet.rb +29 -0
- data/examples/hyperlink.rb +43 -0
- data/examples/images.rb +63 -0
- data/examples/indent.rb +31 -0
- data/examples/merge1.rb +40 -0
- data/examples/merge2.rb +45 -0
- data/examples/merge3.rb +66 -0
- data/examples/merge4.rb +83 -0
- data/examples/merge5.rb +80 -0
- data/examples/merge6.rb +67 -0
- data/examples/outline.rb +255 -0
- data/examples/outline_collapsed.rb +209 -0
- data/examples/panes.rb +113 -0
- data/examples/password_protection.rb +33 -0
- data/examples/properties.rb +34 -0
- data/examples/properties_jp.rb +33 -0
- data/examples/protection.rb +47 -0
- data/examples/regions.rb +53 -0
- data/examples/repeat.rb +43 -0
- data/examples/republic.png +0 -0
- data/examples/right_to_left.rb +27 -0
- data/examples/row_wrap.rb +53 -0
- data/examples/set_first_sheet.rb +14 -0
- data/examples/stats.rb +74 -0
- data/examples/stocks.rb +81 -0
- data/examples/store_formula.rb +15 -0
- data/examples/tab_colors.rb +31 -0
- data/examples/utf8.rb +15 -0
- data/examples/write_arrays.rb +83 -0
- data/html/en/doc_en.html +5946 -0
- data/html/images/a_simple.jpg +0 -0
- data/html/images/area1.jpg +0 -0
- data/html/images/bar1.jpg +0 -0
- data/html/images/chart_area.xls +0 -0
- data/html/images/column1.jpg +0 -0
- data/html/images/data_validation.jpg +0 -0
- data/html/images/line1.jpg +0 -0
- data/html/images/pie1.jpg +0 -0
- data/html/images/regions.jpg +0 -0
- data/html/images/scatter1.jpg +0 -0
- data/html/images/stats.jpg +0 -0
- data/html/images/stock1.jpg +0 -0
- data/html/images/stocks.jpg +0 -0
- data/html/index.html +16 -0
- data/html/style.css +433 -0
- data/lib/writeexcel.rb +1159 -0
- data/lib/writeexcel/biffwriter.rb +223 -0
- data/lib/writeexcel/caller_info.rb +12 -0
- data/lib/writeexcel/cell_range.rb +332 -0
- data/lib/writeexcel/chart.rb +1968 -0
- data/lib/writeexcel/charts/area.rb +154 -0
- data/lib/writeexcel/charts/bar.rb +177 -0
- data/lib/writeexcel/charts/column.rb +156 -0
- data/lib/writeexcel/charts/external.rb +66 -0
- data/lib/writeexcel/charts/line.rb +154 -0
- data/lib/writeexcel/charts/pie.rb +169 -0
- data/lib/writeexcel/charts/scatter.rb +192 -0
- data/lib/writeexcel/charts/stock.rb +213 -0
- data/lib/writeexcel/col_info.rb +87 -0
- data/lib/writeexcel/colors.rb +68 -0
- data/lib/writeexcel/comments.rb +460 -0
- data/lib/writeexcel/compatibility.rb +65 -0
- data/lib/writeexcel/convert_date_time.rb +117 -0
- data/lib/writeexcel/data_validations.rb +370 -0
- data/lib/writeexcel/debug_info.rb +41 -0
- data/lib/writeexcel/embedded_chart.rb +35 -0
- data/lib/writeexcel/excelformula.y +139 -0
- data/lib/writeexcel/excelformulaparser.rb +587 -0
- data/lib/writeexcel/format.rb +1575 -0
- data/lib/writeexcel/formula.rb +987 -0
- data/lib/writeexcel/helper.rb +78 -0
- data/lib/writeexcel/image.rb +218 -0
- data/lib/writeexcel/olewriter.rb +305 -0
- data/lib/writeexcel/outline.rb +24 -0
- data/lib/writeexcel/properties.rb +242 -0
- data/lib/writeexcel/shared_string_table.rb +153 -0
- data/lib/writeexcel/storage_lite.rb +984 -0
- data/lib/writeexcel/workbook.rb +2478 -0
- data/lib/writeexcel/worksheet.rb +6925 -0
- data/lib/writeexcel/worksheets.rb +25 -0
- data/lib/writeexcel/write_file.rb +63 -0
- data/test/excelfile/Chart1.xls +0 -0
- data/test/excelfile/Chart2.xls +0 -0
- data/test/excelfile/Chart3.xls +0 -0
- data/test/excelfile/Chart4.xls +0 -0
- data/test/excelfile/Chart5.xls +0 -0
- data/test/helper.rb +31 -0
- data/test/perl_output/Chart1.xls.data +0 -0
- data/test/perl_output/Chart2.xls.data +0 -0
- data/test/perl_output/Chart3.xls.data +0 -0
- data/test/perl_output/Chart4.xls.data +0 -0
- data/test/perl_output/Chart5.xls.data +0 -0
- data/test/perl_output/README +31 -0
- data/test/perl_output/a_simple.xls +0 -0
- data/test/perl_output/autofilter.xls +0 -0
- data/test/perl_output/biff_add_continue_testdata +0 -0
- data/test/perl_output/chart_area.xls +0 -0
- data/test/perl_output/chart_bar.xls +0 -0
- data/test/perl_output/chart_column.xls +0 -0
- data/test/perl_output/chart_line.xls +0 -0
- data/test/perl_output/chess.xls +0 -0
- data/test/perl_output/colors.xls +0 -0
- data/test/perl_output/comments0.xls +0 -0
- data/test/perl_output/comments1.xls +0 -0
- data/test/perl_output/comments2.xls +0 -0
- data/test/perl_output/data_validate.xls +0 -0
- data/test/perl_output/date_time.xls +0 -0
- data/test/perl_output/defined_name.xls +0 -0
- data/test/perl_output/demo.xls +0 -0
- data/test/perl_output/demo101.bin +0 -0
- data/test/perl_output/demo201.bin +0 -0
- data/test/perl_output/demo301.bin +0 -0
- data/test/perl_output/demo401.bin +0 -0
- data/test/perl_output/demo501.bin +0 -0
- data/test/perl_output/diag_border.xls +0 -0
- data/test/perl_output/f_font_biff +0 -0
- data/test/perl_output/f_font_key +1 -0
- data/test/perl_output/f_xf_biff +0 -0
- data/test/perl_output/file_font_biff +0 -0
- data/test/perl_output/file_font_key +1 -0
- data/test/perl_output/file_xf_biff +0 -0
- data/test/perl_output/formula_result.xls +0 -0
- data/test/perl_output/headers.xls +0 -0
- data/test/perl_output/hidden.xls +0 -0
- data/test/perl_output/hide_zero.xls +0 -0
- data/test/perl_output/hyperlink.xls +0 -0
- data/test/perl_output/images.xls +0 -0
- data/test/perl_output/indent.xls +0 -0
- data/test/perl_output/merge1.xls +0 -0
- data/test/perl_output/merge2.xls +0 -0
- data/test/perl_output/merge3.xls +0 -0
- data/test/perl_output/merge4.xls +0 -0
- data/test/perl_output/merge5.xls +0 -0
- data/test/perl_output/merge6.xls +0 -0
- data/test/perl_output/ole_write_header +0 -0
- data/test/perl_output/outline.xls +0 -0
- data/test/perl_output/outline_collapsed.xls +0 -0
- data/test/perl_output/panes.xls +0 -0
- data/test/perl_output/password_protection.xls +0 -0
- data/test/perl_output/protection.xls +0 -0
- data/test/perl_output/regions.xls +0 -0
- data/test/perl_output/right_to_left.xls +0 -0
- data/test/perl_output/set_first_sheet.xls +0 -0
- data/test/perl_output/stats.xls +0 -0
- data/test/perl_output/stocks.xls +0 -0
- data/test/perl_output/store_formula.xls +0 -0
- data/test/perl_output/tab_colors.xls +0 -0
- data/test/perl_output/unicode_cyrillic.xls +0 -0
- data/test/perl_output/utf8.xls +0 -0
- data/test/perl_output/workbook1.xls +0 -0
- data/test/perl_output/workbook2.xls +0 -0
- data/test/perl_output/ws_colinfo +1 -0
- data/test/perl_output/ws_store_colinfo +0 -0
- data/test/perl_output/ws_store_dimensions +0 -0
- data/test/perl_output/ws_store_filtermode +0 -0
- data/test/perl_output/ws_store_filtermode_off +0 -0
- data/test/perl_output/ws_store_filtermode_on +0 -0
- data/test/perl_output/ws_store_selection +0 -0
- data/test/perl_output/ws_store_window2 +1 -0
- data/test/republic.png +0 -0
- data/test/test_00_IEEE_double.rb +13 -0
- data/test/test_01_add_worksheet.rb +10 -0
- data/test/test_02_merge_formats.rb +49 -0
- data/test/test_04_dimensions.rb +388 -0
- data/test/test_05_rows.rb +175 -0
- data/test/test_06_extsst.rb +74 -0
- data/test/test_11_date_time.rb +475 -0
- data/test/test_12_date_only.rb +525 -0
- data/test/test_13_date_seconds.rb +477 -0
- data/test/test_21_escher.rb +624 -0
- data/test/test_22_mso_drawing_group.rb +741 -0
- data/test/test_23_note.rb +57 -0
- data/test/test_24_txo.rb +74 -0
- data/test/test_25_position_object.rb +80 -0
- data/test/test_26_autofilter.rb +309 -0
- data/test/test_27_autofilter.rb +126 -0
- data/test/test_28_autofilter.rb +156 -0
- data/test/test_29_process_jpg.rb +670 -0
- data/test/test_30_validation_dval.rb +74 -0
- data/test/test_31_validation_dv_strings.rb +123 -0
- data/test/test_32_validation_dv_formula.rb +203 -0
- data/test/test_40_property_types.rb +188 -0
- data/test/test_41_properties.rb +235 -0
- data/test/test_42_set_properties.rb +434 -0
- data/test/test_50_name_stored.rb +295 -0
- data/test/test_51_name_print_area.rb +353 -0
- data/test/test_52_name_print_titles.rb +450 -0
- data/test/test_53_autofilter.rb +199 -0
- data/test/test_60_chart_generic.rb +574 -0
- data/test/test_61_chart_subclasses.rb +84 -0
- data/test/test_62_chart_formats.rb +268 -0
- data/test/test_63_chart_area_formats.rb +645 -0
- data/test/test_biff.rb +71 -0
- data/test/test_big_workbook.rb +17 -0
- data/test/test_compatibility.rb +12 -0
- data/test/test_example_match.rb +3246 -0
- data/test/test_format.rb +1189 -0
- data/test/test_formula.rb +61 -0
- data/test/test_ole.rb +102 -0
- data/test/test_storage_lite.rb +116 -0
- data/test/test_workbook.rb +146 -0
- data/test/test_worksheet.rb +106 -0
- data/utils/add_magic_comment.rb +80 -0
- data/writeexcel.gemspec +278 -0
- data/writeexcel.rdoc +1425 -0
- metadata +292 -0
@@ -0,0 +1,213 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
###############################################################################
|
3
|
+
#
|
4
|
+
# Stock - A writer class for Excel Stock charts.
|
5
|
+
#
|
6
|
+
# Used in conjunction with WriteExcel::Chart.
|
7
|
+
#
|
8
|
+
# See formatting note in WriteExcel::Chart.
|
9
|
+
#
|
10
|
+
# Copyright 2000-2010, John McNamara, jmcnamara@cpan.org
|
11
|
+
#
|
12
|
+
# original written in Perl by John McNamara
|
13
|
+
# converted to Ruby by Hideo Nakamura, cxn03651@msj.biglobe.ne.jp
|
14
|
+
#
|
15
|
+
|
16
|
+
require 'writeexcel'
|
17
|
+
|
18
|
+
module Writeexcel
|
19
|
+
|
20
|
+
class Chart
|
21
|
+
|
22
|
+
# ==SYNOPSIS
|
23
|
+
#
|
24
|
+
# To create a simple Excel file with a Stock chart using WriteExcel:
|
25
|
+
#
|
26
|
+
# #!/usr/bin/ruby -w
|
27
|
+
#
|
28
|
+
# require 'writeexcel'
|
29
|
+
#
|
30
|
+
# workbook = WriteExcel.new('chart.xls')
|
31
|
+
# worksheet = workbook.add_worksheet
|
32
|
+
#
|
33
|
+
# chart = workbook.add_chart(:type => 'Chart::Stock')
|
34
|
+
#
|
35
|
+
# # Add a series for each Open-High-Low-Close.
|
36
|
+
# chart.add_series(:categories => '=Sheet1!$A$2:$A$6', :values => '=Sheet1!$B$2:$B$6')
|
37
|
+
# chart.add_series(:categories => '=Sheet1!$A$2:$A$6', :values => '=Sheet1!$C$2:$C$6')
|
38
|
+
# chart.add_series(:categories => '=Sheet1!$A$2:$A$6', :values => '=Sheet1!$D$2:$D$6')
|
39
|
+
# chart.add_series(:categories => '=Sheet1!$A$2:$A$6', :values => '=Sheet1!$E$2:$E$6')
|
40
|
+
#
|
41
|
+
# # Add the worksheet data the chart refers to.
|
42
|
+
# # ... See the full example below.
|
43
|
+
#
|
44
|
+
# workbook.close
|
45
|
+
#
|
46
|
+
# ==DESCRIPTION
|
47
|
+
#
|
48
|
+
# This module implements Stock charts for WriteExcel. The chart object
|
49
|
+
# is created via the Workbook add_chart() method:
|
50
|
+
#
|
51
|
+
# chart = workbook.add_chart(:type => 'Chart::Stock')
|
52
|
+
#
|
53
|
+
# Once the object is created it can be configured via the following methods
|
54
|
+
# that are common to all chart classes:
|
55
|
+
#
|
56
|
+
# chart.add_series
|
57
|
+
# chart.set_x_axis
|
58
|
+
# chart.set_y_axis
|
59
|
+
# chart.set_title
|
60
|
+
#
|
61
|
+
# These methods are explained in detail in Chart section of WriteExcel.
|
62
|
+
# Class specific methods or settings, if any, are explained below.
|
63
|
+
#
|
64
|
+
# ==Stock Chart Methods
|
65
|
+
#
|
66
|
+
# There aren't currently any stock chart specific methods.
|
67
|
+
# See the TODO section of Chart section in WriteExcel.
|
68
|
+
#
|
69
|
+
# The default Stock chart is an Open-High-Low-Close chart.
|
70
|
+
# A series must be added for each of these data sources.
|
71
|
+
#
|
72
|
+
# The default Stock chart is in black and white. User defined colours
|
73
|
+
# will be added at a later stage.
|
74
|
+
#
|
75
|
+
# ==EXAMPLE
|
76
|
+
#
|
77
|
+
# Here is a complete example that demonstrates most of the available features
|
78
|
+
# when creating a Stock chart.
|
79
|
+
#
|
80
|
+
# #!/usr/bin/ruby -w
|
81
|
+
#
|
82
|
+
# require 'writeexcel'
|
83
|
+
#
|
84
|
+
# workbook = WriteExcel.new('chart_stock_ex.xls')
|
85
|
+
# worksheet = workbook.add_worksheet
|
86
|
+
# bold = workbook.add_format(:bold => 1)
|
87
|
+
# date_format = workbook.add_format(:num_format => 'dd/mm/yyyy')
|
88
|
+
#
|
89
|
+
# # Add the worksheet data that the charts will refer to.
|
90
|
+
# headings = [ 'Date', 'Open', 'High', 'Low', 'Close' ]
|
91
|
+
# data = [
|
92
|
+
# [ '2009-08-23', 110.75, 113.48, 109.05, 109.40 ],
|
93
|
+
# [ '2009-08-24', 111.24, 111.60, 103.57, 104.87 ],
|
94
|
+
# [ '2009-08-25', 104.96, 108.00, 103.88, 106.00 ],
|
95
|
+
# [ '2009-08-26', 104.95, 107.95, 104.66, 107.91 ],
|
96
|
+
# [ '2009-08-27', 108.10, 108.62, 105.69, 106.15 ]
|
97
|
+
# ]
|
98
|
+
#
|
99
|
+
# worksheet.write('A1', headings, bold)
|
100
|
+
#
|
101
|
+
# row = 1
|
102
|
+
# data.each do |d|
|
103
|
+
# worksheet.write(row, 0, d[0], date_format)
|
104
|
+
# worksheet.write(row, 1, d[1])
|
105
|
+
# worksheet.write(row, 2, d[2])
|
106
|
+
# worksheet.write(row, 3, d[3])
|
107
|
+
# worksheet.write(row, 4, d[4])
|
108
|
+
# row += 1
|
109
|
+
# end
|
110
|
+
#
|
111
|
+
# # Create a new chart object. In this case an embedded chart.
|
112
|
+
# chart = workbook.add_chart(:type => 'Chart::Stock', ::embedded => 1)
|
113
|
+
#
|
114
|
+
# # Add a series for each of the Open-High-Low-Close columns.
|
115
|
+
# chart.add_series(
|
116
|
+
# :categories => '=Sheet1!$A$2:$A$6',
|
117
|
+
# :values => '=Sheet1!$B$2:$B$6',
|
118
|
+
# :name => 'Open'
|
119
|
+
# )
|
120
|
+
#
|
121
|
+
# chart.add_series(
|
122
|
+
# :categories => '=Sheet1!$A$2:$A$6',
|
123
|
+
# :values => '=Sheet1!$C$2:$C$6',
|
124
|
+
# :name => 'High'
|
125
|
+
# )
|
126
|
+
#
|
127
|
+
# chart.add_series(
|
128
|
+
# :categories => '=Sheet1!$A$2:$A$6',
|
129
|
+
# :values => '=Sheet1!$D$2:$D$6',
|
130
|
+
# :name => 'Low'
|
131
|
+
# )
|
132
|
+
#
|
133
|
+
# chart.add_series(
|
134
|
+
# :categories => '=Sheet1!$A$2:$A$6',
|
135
|
+
# :values => '=Sheet1!$E$2:$E$6',
|
136
|
+
# :name => 'Close'
|
137
|
+
# )
|
138
|
+
#
|
139
|
+
# # Add a chart title and some axis labels.
|
140
|
+
# chart.set_title(:name => 'Open-High-Low-Close')
|
141
|
+
# chart.set_x_axis(:name => 'Date')
|
142
|
+
# chart.set_y_axis(:name => 'Share price')
|
143
|
+
#
|
144
|
+
# # Insert the chart into the worksheet (with an offset).
|
145
|
+
# worksheet.insert_chart('F2', chart, 25, 10)
|
146
|
+
#
|
147
|
+
# workbook.close
|
148
|
+
#
|
149
|
+
class Stock < Chart
|
150
|
+
###############################################################################
|
151
|
+
#
|
152
|
+
# new()
|
153
|
+
#
|
154
|
+
#
|
155
|
+
def initialize(*args) # :nodoc:
|
156
|
+
super
|
157
|
+
end
|
158
|
+
|
159
|
+
###############################################################################
|
160
|
+
#
|
161
|
+
# _store_chart_type()
|
162
|
+
#
|
163
|
+
# Implementation of the abstract method from the specific chart class.
|
164
|
+
#
|
165
|
+
# Write the LINE chart BIFF record. A stock chart uses the same LINE record
|
166
|
+
# as a line chart but with additional DROPBAR and CHARTLINE records to define
|
167
|
+
# the stock style.
|
168
|
+
#
|
169
|
+
def store_chart_type # :nodoc:
|
170
|
+
record = 0x1018 # Record identifier.
|
171
|
+
length = 0x0002 # Number of bytes to follow.
|
172
|
+
grbit = 0x0000 # Option flags.
|
173
|
+
|
174
|
+
store_simple(record, length, grbit)
|
175
|
+
end
|
176
|
+
|
177
|
+
###############################################################################
|
178
|
+
#
|
179
|
+
# _store_marker_dataformat_stream(). Overridden.
|
180
|
+
#
|
181
|
+
# This is an implementation of the parent abstract method to define
|
182
|
+
# properties of markers, linetypes, pie formats and other.
|
183
|
+
#
|
184
|
+
def store_marker_dataformat_stream # :nodoc:
|
185
|
+
store_dropbar
|
186
|
+
store_begin
|
187
|
+
store_lineformat(0x00000000, 0x0000, 0xFFFF, 0x0001, 0x004F)
|
188
|
+
store_areaformat(0x00FFFFFF, 0x0000, 0x01, 0x01, 0x09, 0x08)
|
189
|
+
store_end
|
190
|
+
|
191
|
+
store_dropbar
|
192
|
+
store_begin
|
193
|
+
store_lineformat(0x00000000, 0x0000, 0xFFFF, 0x0001, 0x004F)
|
194
|
+
store_areaformat(0x0000, 0x00FFFFFF, 0x01, 0x01, 0x08, 0x09)
|
195
|
+
store_end
|
196
|
+
|
197
|
+
store_chartline
|
198
|
+
store_lineformat(0x00000000, 0x0000, 0xFFFF, 0x0000, 0x004F)
|
199
|
+
|
200
|
+
|
201
|
+
store_dataformat(0x0000, 0xFFFD, 0x0000)
|
202
|
+
store_begin
|
203
|
+
store_3dbarshape
|
204
|
+
store_lineformat(0x00000000, 0x0005, 0xFFFF, 0x0000, 0x004F)
|
205
|
+
store_areaformat(0x00000000, 0x0000, 0x00, 0x01, 0x4D, 0x4D)
|
206
|
+
store_pieformat
|
207
|
+
store_markerformat(0x00, 0x00, 0x00, 0x00, 0x4D, 0x4D, 0x3C)
|
208
|
+
store_end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end # class Chart
|
212
|
+
|
213
|
+
end # module Writeexcel
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module Writeexcel
|
2
|
+
|
3
|
+
class Worksheet < BIFFWriter
|
4
|
+
require 'writeexcel/helper'
|
5
|
+
|
6
|
+
class ColInfo
|
7
|
+
attr_reader :level
|
8
|
+
|
9
|
+
#
|
10
|
+
# new(firstcol, lastcol, width, [format, hidden, level, collapsed])
|
11
|
+
#
|
12
|
+
# firstcol : First formatted column
|
13
|
+
# lastcol : Last formatted column
|
14
|
+
# width : Col width in user units, 8.43 is default
|
15
|
+
# format : format object
|
16
|
+
# hidden : hidden flag
|
17
|
+
# level : outline level
|
18
|
+
# collapsed : ?
|
19
|
+
#
|
20
|
+
def initialize(*args)
|
21
|
+
@firstcol, @lastcol, @width, @format, @hidden, @level, @collapsed = args
|
22
|
+
@width ||= 8.43 # default width
|
23
|
+
@level ||= 0 # default level
|
24
|
+
end
|
25
|
+
|
26
|
+
# Write BIFF record COLINFO to define column widths
|
27
|
+
#
|
28
|
+
# Note: The SDK says the record length is 0x0B but Excel writes a 0x0C
|
29
|
+
# length record.
|
30
|
+
#
|
31
|
+
def biff_record
|
32
|
+
record = 0x007D # Record identifier
|
33
|
+
length = 0x000B # Number of bytes to follow
|
34
|
+
|
35
|
+
coldx = (pixels * 256 / 7).to_i # Col width in internal units
|
36
|
+
reserved = 0x00 # Reserved
|
37
|
+
|
38
|
+
header = [record, length].pack("vv")
|
39
|
+
data = [@firstcol, @lastcol, coldx,
|
40
|
+
ixfe, grbit, reserved].pack("vvvvvC")
|
41
|
+
[header, data]
|
42
|
+
end
|
43
|
+
|
44
|
+
# Excel rounds the column width to the nearest pixel. Therefore we first
|
45
|
+
# convert to pixels and then to the internal units. The pixel to users-units
|
46
|
+
# relationship is different for values less than 1.
|
47
|
+
#
|
48
|
+
def pixels
|
49
|
+
if @width < 1
|
50
|
+
result = @width * 12
|
51
|
+
else
|
52
|
+
result = @width * 7 + 5
|
53
|
+
end
|
54
|
+
result.to_i
|
55
|
+
end
|
56
|
+
|
57
|
+
def ixfe
|
58
|
+
if @format && @format.respond_to?(:xf_index)
|
59
|
+
ixfe = @format.xf_index
|
60
|
+
else
|
61
|
+
ixfe = 0x0F
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Set the limits for the outline levels (0 <= x <= 7).
|
66
|
+
def level
|
67
|
+
if @level < 0
|
68
|
+
0
|
69
|
+
elsif 7 < @level
|
70
|
+
7
|
71
|
+
else
|
72
|
+
@level
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Set the options flags. (See set_row() for more details).
|
77
|
+
def grbit
|
78
|
+
grbit = 0x0000 # Option flags
|
79
|
+
grbit |= 0x0001 if @hidden && @hidden != 0
|
80
|
+
grbit |= level << 8
|
81
|
+
grbit |= 0x1000 if @collapsed && @collapsed != 0
|
82
|
+
grbit
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Writeexcel
|
4
|
+
|
5
|
+
class Colors
|
6
|
+
COLORS = {
|
7
|
+
:aqua => 0x0F,
|
8
|
+
:cyan => 0x0F,
|
9
|
+
:black => 0x08,
|
10
|
+
:blue => 0x0C,
|
11
|
+
:brown => 0x10,
|
12
|
+
:magenta => 0x0E,
|
13
|
+
:fuchsia => 0x0E,
|
14
|
+
:gray => 0x17,
|
15
|
+
:grey => 0x17,
|
16
|
+
:green => 0x11,
|
17
|
+
:lime => 0x0B,
|
18
|
+
:navy => 0x12,
|
19
|
+
:orange => 0x35,
|
20
|
+
:pink => 0x21,
|
21
|
+
:purple => 0x14,
|
22
|
+
:red => 0x0A,
|
23
|
+
:silver => 0x16,
|
24
|
+
:white => 0x09,
|
25
|
+
:yellow => 0x0D,
|
26
|
+
} # :nodoc:
|
27
|
+
|
28
|
+
###############################################################################
|
29
|
+
#
|
30
|
+
# get_color(colour)
|
31
|
+
#
|
32
|
+
# Used in conjunction with the set_xxx_color methods to convert a color
|
33
|
+
# string into a number. Color range is 0..63 but we will restrict it
|
34
|
+
# to 8..63 to comply with Gnumeric. Colors 0..7 are repeated in 8..15.
|
35
|
+
#
|
36
|
+
def get_color(color = nil) # :nodoc:
|
37
|
+
if color.respond_to?(:to_int) && color.respond_to?(:+)
|
38
|
+
# the default color if arg is outside range,
|
39
|
+
if color < 0 || 63 < color
|
40
|
+
0x7FFF
|
41
|
+
# or an index < 8 mapped into the correct range,
|
42
|
+
elsif color < 8
|
43
|
+
(color + 8).to_i
|
44
|
+
# or an integer in the valid range
|
45
|
+
else
|
46
|
+
color.to_i
|
47
|
+
end
|
48
|
+
elsif color.respond_to?(:to_sym)
|
49
|
+
color = color.downcase.to_sym if color.respond_to?(:to_str)
|
50
|
+
# or the color string converted to an integer,
|
51
|
+
if COLORS.has_key?(color)
|
52
|
+
COLORS[color]
|
53
|
+
# or the default color if string is unrecognised,
|
54
|
+
else
|
55
|
+
0x7FFF
|
56
|
+
end
|
57
|
+
else
|
58
|
+
0x7FFF
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def inspect
|
63
|
+
to_s
|
64
|
+
end
|
65
|
+
end # class Colors
|
66
|
+
|
67
|
+
end # module Writeexcel
|
68
|
+
|
@@ -0,0 +1,460 @@
|
|
1
|
+
module Writeexcel
|
2
|
+
|
3
|
+
class Worksheet < BIFFWriter
|
4
|
+
require 'writeexcel/helper'
|
5
|
+
|
6
|
+
class Collection
|
7
|
+
def initialize
|
8
|
+
@items = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def <<(item)
|
12
|
+
if @items[item.row]
|
13
|
+
@items[item.row][item.col] = item
|
14
|
+
else
|
15
|
+
@items[item.row] = { item.col => item }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def array
|
20
|
+
return @array if @array
|
21
|
+
|
22
|
+
@array = []
|
23
|
+
@items.keys.sort.each do |row|
|
24
|
+
@items[row].keys.sort.each do |col|
|
25
|
+
@array << @items[row][col]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
@array
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
class Comments < Collection
|
34
|
+
attr_writer :visible
|
35
|
+
|
36
|
+
def initialize
|
37
|
+
super
|
38
|
+
@visible = false
|
39
|
+
end
|
40
|
+
|
41
|
+
def visible?
|
42
|
+
@visible
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class Comment
|
47
|
+
attr_reader :row, :col, :string, :encoding, :author, :author_encoding, :visible, :color, :vertices
|
48
|
+
|
49
|
+
def initialize(worksheet, row, col, string, options = {})
|
50
|
+
@worksheet = worksheet
|
51
|
+
@row, @col = row, col
|
52
|
+
@params = params_with(options)
|
53
|
+
@string, @params[:encoding] = string_and_encoding(string, @params[:encoding], 'comment')
|
54
|
+
|
55
|
+
# Limit the string to the max number of chars (not bytes).
|
56
|
+
max_len = 32767
|
57
|
+
max_len = max_len * 2 if @params[:encoding] != 0
|
58
|
+
|
59
|
+
if @string.bytesize > max_len
|
60
|
+
@string = @string[0 .. max_len]
|
61
|
+
end
|
62
|
+
@encoding = @params[:encoding]
|
63
|
+
@author = @params[:author]
|
64
|
+
@author_encoding = @params[:author_encoding]
|
65
|
+
@visible = @params[:visible]
|
66
|
+
@color = @params[:color]
|
67
|
+
@vertices = calc_vertices
|
68
|
+
end
|
69
|
+
|
70
|
+
def store_comment_record(i, num_objects, num_comments, spid)
|
71
|
+
str_len = string.bytesize
|
72
|
+
str_len = str_len / 2 if encoding != 0 # Num of chars not bytes.
|
73
|
+
|
74
|
+
spid = store_comment_mso_drawing_record(i, num_objects, num_comments, spid, visible, color, vertices)
|
75
|
+
store_obj_comment(num_objects + i + 1)
|
76
|
+
store_mso_drawing_text_box
|
77
|
+
store_txo(str_len)
|
78
|
+
store_txo_continue_1(string, encoding)
|
79
|
+
formats = [[0, 9], [str_len, 0]]
|
80
|
+
store_txo_continue_2(formats)
|
81
|
+
spid
|
82
|
+
end
|
83
|
+
|
84
|
+
#
|
85
|
+
# Write the worksheet NOTE record that is part of cell comments.
|
86
|
+
#
|
87
|
+
def store_note_record(obj_id) #:nodoc:
|
88
|
+
comment_author = author
|
89
|
+
comment_author_enc = author_encoding
|
90
|
+
ruby_19 { comment_author = [comment_author].pack('a*') if comment_author.ascii_only? }
|
91
|
+
record = 0x001C # Record identifier
|
92
|
+
length = 0x000C # Bytes to follow
|
93
|
+
|
94
|
+
comment_author = '' unless comment_author
|
95
|
+
comment_author_enc = 0 unless author_encoding
|
96
|
+
|
97
|
+
# Use the visible flag if set by the user or else use the worksheet value.
|
98
|
+
# The flag is also set in store_mso_opt_comment() but with the opposite
|
99
|
+
# value.
|
100
|
+
if visible
|
101
|
+
comment_visible = visible != 0 ? 0x0002 : 0x0000
|
102
|
+
else
|
103
|
+
comment_visible = @worksheet.comments_visible? ? 0x0002 : 0x0000
|
104
|
+
end
|
105
|
+
|
106
|
+
# Get the number of chars in the author string (not bytes).
|
107
|
+
num_chars = comment_author.bytesize
|
108
|
+
num_chars = num_chars / 2 if comment_author_enc != 0 && comment_author_enc
|
109
|
+
|
110
|
+
# Null terminate the author string.
|
111
|
+
comment_author =
|
112
|
+
ruby_18 { comment_author + "\0" } ||
|
113
|
+
ruby_19 { comment_author.force_encoding('BINARY') + "\0".force_encoding('BINARY') }
|
114
|
+
|
115
|
+
# Pack the record.
|
116
|
+
data = [@row, @col, comment_visible, obj_id, num_chars, comment_author_enc].pack("vvvvvC")
|
117
|
+
|
118
|
+
length = data.bytesize + comment_author.bytesize
|
119
|
+
header = [record, length].pack("vv")
|
120
|
+
|
121
|
+
append(header, data, comment_author)
|
122
|
+
end
|
123
|
+
|
124
|
+
#
|
125
|
+
# Write the Escher Opt record that is part of MSODRAWING.
|
126
|
+
#
|
127
|
+
def store_mso_opt_comment(spid, visible = nil, colour = 0x50) #:nodoc:
|
128
|
+
type = 0xF00B
|
129
|
+
version = 3
|
130
|
+
instance = 9
|
131
|
+
data = ''
|
132
|
+
length = 54
|
133
|
+
|
134
|
+
# Use the visible flag if set by the user or else use the worksheet value.
|
135
|
+
# Note that the value used is the opposite of Comment#note_record.
|
136
|
+
#
|
137
|
+
if visible
|
138
|
+
visible = visible != 0 ? 0x0000 : 0x0002
|
139
|
+
else
|
140
|
+
visible = @worksheet.comments_visible? ? 0x0000 : 0x0002
|
141
|
+
end
|
142
|
+
|
143
|
+
data = [spid].pack('V') +
|
144
|
+
['0000BF00080008005801000000008101'].pack("H*") +
|
145
|
+
[colour].pack("C") +
|
146
|
+
['000008830150000008BF011000110001'+'02000000003F0203000300BF03'].pack("H*") +
|
147
|
+
[visible].pack('v') +
|
148
|
+
['0A00'].pack('H*')
|
149
|
+
|
150
|
+
@worksheet.add_mso_generic(type, version, instance, data, length)
|
151
|
+
end
|
152
|
+
|
153
|
+
#
|
154
|
+
# OBJ record that is part of cell comments.
|
155
|
+
# obj_id # Object ID number.
|
156
|
+
#
|
157
|
+
def obj_comment_record(obj_id) #:nodoc:
|
158
|
+
record = 0x005D # Record identifier
|
159
|
+
length = 0x0034 # Bytes to follow
|
160
|
+
|
161
|
+
obj_type = 0x0019 # Object type (comment).
|
162
|
+
data = '' # Record data.
|
163
|
+
|
164
|
+
sub_record = 0x0000 # Sub-record identifier.
|
165
|
+
sub_length = 0x0000 # Length of sub-record.
|
166
|
+
sub_data = '' # Data of sub-record.
|
167
|
+
options = 0x4011
|
168
|
+
reserved = 0x0000
|
169
|
+
|
170
|
+
# Add ftCmo (common object data) subobject
|
171
|
+
sub_record = 0x0015 # ftCmo
|
172
|
+
sub_length = 0x0012
|
173
|
+
sub_data = [obj_type, obj_id, options, reserved, reserved, reserved].pack( "vvvVVV")
|
174
|
+
data = [sub_record, sub_length].pack("vv") + sub_data
|
175
|
+
|
176
|
+
# Add ftNts (note structure) subobject
|
177
|
+
sub_record = 0x000D # ftNts
|
178
|
+
sub_length = 0x0016
|
179
|
+
sub_data = [reserved,reserved,reserved,reserved,reserved,reserved].pack( "VVVVVv")
|
180
|
+
data += [sub_record, sub_length].pack("vv") + sub_data
|
181
|
+
|
182
|
+
# Add ftEnd (end of object) subobject
|
183
|
+
sub_record = 0x0000 # ftNts
|
184
|
+
sub_length = 0x0000
|
185
|
+
data += [sub_record, sub_length].pack("vv")
|
186
|
+
|
187
|
+
# Pack the record.
|
188
|
+
header = [record, length].pack("vv")
|
189
|
+
|
190
|
+
header + data
|
191
|
+
end
|
192
|
+
|
193
|
+
private
|
194
|
+
|
195
|
+
def params_with(options)
|
196
|
+
params = default_params.update(options)
|
197
|
+
|
198
|
+
# Ensure that a width and height have been set.
|
199
|
+
params[:width] = default_width unless params[:width] && params[:width] != 0
|
200
|
+
params[:width] = params[:width] * params[:x_scale] if params[:x_scale] != 0
|
201
|
+
params[:height] = default_height unless params[:height] && params[:height] != 0
|
202
|
+
params[:height] = params[:height] * params[:y_scale] if params[:y_scale] != 0
|
203
|
+
|
204
|
+
params[:author], params[:author_encoding] =
|
205
|
+
string_and_encoding(params[:author], params[:author_encoding], 'author')
|
206
|
+
|
207
|
+
# Set the comment background colour.
|
208
|
+
params[:color] = background_color(params[:color])
|
209
|
+
|
210
|
+
# Set the default start cell and offsets for the comment. These are
|
211
|
+
# generally fixed in relation to the parent cell. However there are
|
212
|
+
# some edge cases for cells at the, er, edges.
|
213
|
+
#
|
214
|
+
params[:start_row] = default_start_row unless params[:start_row]
|
215
|
+
params[:y_offset] = default_y_offset unless params[:y_offset]
|
216
|
+
params[:start_col] = default_start_col unless params[:start_col]
|
217
|
+
params[:x_offset] = default_x_offset unless params[:x_offset]
|
218
|
+
|
219
|
+
params
|
220
|
+
end
|
221
|
+
|
222
|
+
def default_params
|
223
|
+
{
|
224
|
+
:author => '',
|
225
|
+
:author_encoding => 0,
|
226
|
+
:encoding => 0,
|
227
|
+
:color => nil,
|
228
|
+
:start_cell => nil,
|
229
|
+
:start_col => nil,
|
230
|
+
:start_row => nil,
|
231
|
+
:visible => nil,
|
232
|
+
:width => default_width,
|
233
|
+
:height => default_height,
|
234
|
+
:x_offset => nil,
|
235
|
+
:x_scale => 1,
|
236
|
+
:y_offset => nil,
|
237
|
+
:y_scale => 1
|
238
|
+
}
|
239
|
+
end
|
240
|
+
|
241
|
+
def default_width
|
242
|
+
128
|
243
|
+
end
|
244
|
+
|
245
|
+
def default_height
|
246
|
+
74
|
247
|
+
end
|
248
|
+
|
249
|
+
def default_start_row
|
250
|
+
case @row
|
251
|
+
when 0 then 0
|
252
|
+
when 65533 then 65529
|
253
|
+
when 65534 then 65530
|
254
|
+
when 65535 then 65531
|
255
|
+
else @row -1
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
def default_y_offset
|
260
|
+
case @row
|
261
|
+
when 0 then 2
|
262
|
+
when 65533 then 4
|
263
|
+
when 65534 then 4
|
264
|
+
when 65535 then 2
|
265
|
+
else 7
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
def default_start_col
|
270
|
+
case @col
|
271
|
+
when 253 then 250
|
272
|
+
when 254 then 251
|
273
|
+
when 255 then 252
|
274
|
+
else @col + 1
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
def default_x_offset
|
279
|
+
case @col
|
280
|
+
when 253 then 49
|
281
|
+
when 254 then 49
|
282
|
+
when 255 then 49
|
283
|
+
else 15
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
def string_and_encoding(string, encoding, type)
|
288
|
+
string = convert_to_ascii_if_ascii(string)
|
289
|
+
if encoding != 0
|
290
|
+
raise "Uneven number of bytes in #{type} string" if string.bytesize % 2 != 0
|
291
|
+
# Change from UTF-16BE to UTF-16LE
|
292
|
+
string = utf16be_to_16le(string)
|
293
|
+
# Handle utf8 strings
|
294
|
+
else
|
295
|
+
if is_utf8?(string)
|
296
|
+
string = NKF.nkf('-w16L0 -m0 -W', string)
|
297
|
+
ruby_19 { string.force_encoding('UTF-16LE') }
|
298
|
+
encoding = 1
|
299
|
+
end
|
300
|
+
end
|
301
|
+
[string, encoding]
|
302
|
+
end
|
303
|
+
|
304
|
+
def background_color(color)
|
305
|
+
color = Colors.new.get_color(color)
|
306
|
+
color = 0x50 if color == 0x7FFF # Default color.
|
307
|
+
color
|
308
|
+
end
|
309
|
+
|
310
|
+
# Calculate the positions of comment object.
|
311
|
+
def calc_vertices
|
312
|
+
@worksheet.position_object( @params[:start_col],
|
313
|
+
@params[:start_row],
|
314
|
+
@params[:x_offset],
|
315
|
+
@params[:y_offset],
|
316
|
+
@params[:width],
|
317
|
+
@params[:height]
|
318
|
+
)
|
319
|
+
end
|
320
|
+
|
321
|
+
def store_comment_mso_drawing_record(i, num_objects, num_comments, spid, visible, color, vertices)
|
322
|
+
if i == 0 && num_objects == 0
|
323
|
+
# Write the parent MSODRAWIING record.
|
324
|
+
dg_length = 200 + 128 * (num_comments - 1)
|
325
|
+
spgr_length = 176 + 128 * (num_comments - 1)
|
326
|
+
|
327
|
+
data = @worksheet.store_parent_mso_record(dg_length, spgr_length, spid)
|
328
|
+
spid += 1
|
329
|
+
else
|
330
|
+
data = ''
|
331
|
+
end
|
332
|
+
data += @worksheet.store_mso_sp_container(120) + @worksheet.store_mso_sp(202, spid, 0x0A00)
|
333
|
+
spid += 1
|
334
|
+
data +=
|
335
|
+
store_mso_opt_comment(0x80, visible, color) +
|
336
|
+
@worksheet.store_mso_client_anchor(3, *vertices) +
|
337
|
+
@worksheet.store_mso_client_data
|
338
|
+
record = 0x00EC # Record identifier
|
339
|
+
length = data.bytesize
|
340
|
+
header = [record, length].pack("vv")
|
341
|
+
append(header, data)
|
342
|
+
|
343
|
+
spid
|
344
|
+
end
|
345
|
+
|
346
|
+
def store_obj_comment(obj_id)
|
347
|
+
append(obj_comment_record(obj_id))
|
348
|
+
end
|
349
|
+
|
350
|
+
#
|
351
|
+
# Write the MSODRAWING ClientTextbox record that is part of comments.
|
352
|
+
#
|
353
|
+
def store_mso_drawing_text_box #:nodoc:
|
354
|
+
record = 0x00EC # Record identifier
|
355
|
+
length = 0x0008 # Bytes to follow
|
356
|
+
|
357
|
+
data = store_mso_client_text_box
|
358
|
+
header = [record, length].pack('vv')
|
359
|
+
|
360
|
+
append(header, data)
|
361
|
+
end
|
362
|
+
|
363
|
+
#
|
364
|
+
# Write the Escher ClientTextbox record that is part of MSODRAWING.
|
365
|
+
#
|
366
|
+
def store_mso_client_text_box #:nodoc:
|
367
|
+
type = 0xF00D
|
368
|
+
version = 0
|
369
|
+
instance = 0
|
370
|
+
data = ''
|
371
|
+
length = 0
|
372
|
+
|
373
|
+
@worksheet.add_mso_generic(type, version, instance, data, length)
|
374
|
+
end
|
375
|
+
|
376
|
+
#
|
377
|
+
# Write the worksheet TXO record that is part of cell comments.
|
378
|
+
# string_len # Length of the note text.
|
379
|
+
# format_len # Length of the format runs.
|
380
|
+
# rotation # Options
|
381
|
+
#
|
382
|
+
def store_txo(string_len, format_len = 16, rotation = 0) #:nodoc:
|
383
|
+
record = 0x01B6 # Record identifier
|
384
|
+
length = 0x0012 # Bytes to follow
|
385
|
+
|
386
|
+
grbit = 0x0212 # Options
|
387
|
+
reserved = 0x0000 # Options
|
388
|
+
|
389
|
+
# Pack the record.
|
390
|
+
header = [record, length].pack('vv')
|
391
|
+
data = [grbit, rotation, reserved, reserved, string_len, format_len, reserved].pack("vvVvvvV")
|
392
|
+
append(header, data)
|
393
|
+
end
|
394
|
+
|
395
|
+
#
|
396
|
+
# Write the first CONTINUE record to follow the TXO record. It contains the
|
397
|
+
# text data.
|
398
|
+
# string # Comment string.
|
399
|
+
# encoding # Encoding of the string.
|
400
|
+
#
|
401
|
+
def store_txo_continue_1(string, encoding = 0) #:nodoc:
|
402
|
+
# Split long comment strings into smaller continue blocks if necessary.
|
403
|
+
# We can't let BIFFwriter::_add_continue() handled this since an extra
|
404
|
+
# encoding byte has to be added similar to the SST block.
|
405
|
+
#
|
406
|
+
# We make the limit size smaller than the add_continue() size and even
|
407
|
+
# so that UTF16 chars occur in the same block.
|
408
|
+
#
|
409
|
+
limit = 8218
|
410
|
+
while string.bytesize > limit
|
411
|
+
string[0 .. limit] = ""
|
412
|
+
tmp_str = string
|
413
|
+
data = [encoding].pack("C") +
|
414
|
+
ruby_18 { tmp_str } ||
|
415
|
+
ruby_19 { tmp_str.force_encoding('ASCII-8BIT') }
|
416
|
+
length = data.bytesize
|
417
|
+
header = [record, length].pack('vv')
|
418
|
+
|
419
|
+
append(header, data)
|
420
|
+
end
|
421
|
+
|
422
|
+
# Pack the record.
|
423
|
+
data =
|
424
|
+
ruby_18 { [encoding].pack("C") + string } ||
|
425
|
+
ruby_19 { [encoding].pack("C") + string.force_encoding('ASCII-8BIT') }
|
426
|
+
|
427
|
+
record = 0x003C # Record identifier
|
428
|
+
length = data.bytesize
|
429
|
+
header = [record, length].pack('vv')
|
430
|
+
|
431
|
+
append(header, data)
|
432
|
+
end
|
433
|
+
|
434
|
+
#
|
435
|
+
# Write the second CONTINUE record to follow the TXO record. It contains the
|
436
|
+
# formatting information for the string.
|
437
|
+
# formats # Formatting information
|
438
|
+
#
|
439
|
+
def store_txo_continue_2(formats) #:nodoc:
|
440
|
+
# Pack the record.
|
441
|
+
data = ''
|
442
|
+
|
443
|
+
formats.each do |a_ref|
|
444
|
+
data += [a_ref[0], a_ref[1], 0x0].pack('vvV')
|
445
|
+
end
|
446
|
+
|
447
|
+
record = 0x003C # Record identifier
|
448
|
+
length = data.bytesize
|
449
|
+
header = [record, length].pack("vv")
|
450
|
+
|
451
|
+
append(header, data)
|
452
|
+
end
|
453
|
+
|
454
|
+
def append(*args)
|
455
|
+
@worksheet.append(*args)
|
456
|
+
end
|
457
|
+
end
|
458
|
+
end
|
459
|
+
|
460
|
+
end
|