write_xlsx 0.89.0 → 1.01.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/Changes +98 -0
- data/LICENSE.txt +1 -1
- data/README.md +2 -2
- data/examples/a_simple.rb +2 -7
- data/examples/add_vba_project.rb +1 -1
- data/examples/array_formula.rb +1 -1
- data/examples/chart_area.rb +5 -2
- data/examples/chart_bar.rb +5 -2
- data/examples/chart_clustered.rb +1 -1
- data/examples/chart_column.rb +5 -2
- data/examples/chart_combined.rb +1 -1
- data/examples/chart_data_table.rb +9 -3
- data/examples/chart_data_tools.rb +25 -7
- data/examples/chart_doughnut.rb +17 -5
- data/examples/chart_gauge.rb +73 -0
- data/examples/chart_line.rb +5 -2
- data/examples/chart_pareto.rb +1 -1
- data/examples/chart_pie.rb +9 -3
- data/examples/chart_radar.rb +13 -4
- data/examples/chart_scatter.rb +5 -2
- data/examples/chart_secondary_axis.rb +5 -2
- data/examples/chart_stock.rb +1 -1
- data/examples/chart_styles.rb +1 -1
- data/examples/colors.rb +1 -1
- data/examples/conditional_format.rb +73 -46
- data/examples/data_validate.rb +1 -1
- data/examples/date_time.rb +1 -1
- data/examples/demo.rb +5 -8
- data/examples/formats.rb +1 -1
- data/examples/headers.rb +1 -1
- data/examples/hide_row_col.rb +1 -1
- data/examples/hide_sheet.rb +1 -1
- data/examples/hyperlink1.rb +5 -12
- data/examples/indent.rb +1 -1
- data/examples/macros.rb +1 -1
- data/examples/merge1.rb +1 -1
- data/examples/merge2.rb +1 -1
- data/examples/merge3.rb +1 -1
- data/examples/merge4.rb +1 -1
- data/examples/merge5.rb +1 -1
- data/examples/merge6.rb +1 -1
- data/examples/outline.rb +1 -1
- data/examples/outline_collapsed.rb +1 -1
- data/examples/panes.rb +1 -1
- data/examples/properties.rb +1 -1
- data/examples/regions.rb +1 -1
- data/examples/rich_strings.rb +1 -1
- data/examples/right_to_left.rb +1 -1
- data/examples/shape1.rb +1 -1
- data/examples/shape2.rb +1 -1
- data/examples/shape3.rb +1 -1
- data/examples/shape4.rb +1 -1
- data/examples/shape5.rb +1 -1
- data/examples/shape6.rb +1 -1
- data/examples/shape7.rb +1 -1
- data/examples/shape8.rb +1 -1
- data/examples/shape_all.rb +1 -1
- data/examples/sparklines1.rb +1 -1
- data/examples/sparklines2.rb +1 -1
- data/examples/stats.rb +1 -1
- data/examples/stats_ext.rb +1 -1
- data/examples/stocks.rb +1 -1
- data/examples/tab_colors.rb +1 -1
- data/examples/tables.rb +1 -1
- data/lib/write_xlsx/chart.rb +124 -240
- data/lib/write_xlsx/chart/area.rb +1 -1
- data/lib/write_xlsx/chart/axis.rb +4 -4
- data/lib/write_xlsx/chart/bar.rb +1 -1
- data/lib/write_xlsx/chart/caption.rb +3 -1
- data/lib/write_xlsx/chart/column.rb +1 -1
- data/lib/write_xlsx/chart/doughnut.rb +1 -1
- data/lib/write_xlsx/chart/legend.rb +14 -0
- data/lib/write_xlsx/chart/line.rb +1 -1
- data/lib/write_xlsx/chart/pie.rb +32 -15
- data/lib/write_xlsx/chart/radar.rb +1 -1
- data/lib/write_xlsx/chart/scatter.rb +1 -1
- data/lib/write_xlsx/chart/series.rb +11 -7
- data/lib/write_xlsx/chart/stock.rb +1 -1
- data/lib/write_xlsx/chartsheet.rb +35 -7
- data/lib/write_xlsx/drawing.rb +28 -8
- data/lib/write_xlsx/format.rb +19 -15
- data/lib/write_xlsx/package/comments.rb +57 -54
- data/lib/write_xlsx/package/conditional_format.rb +360 -39
- data/lib/write_xlsx/package/content_types.rb +10 -0
- data/lib/write_xlsx/package/core.rb +8 -6
- data/lib/write_xlsx/package/custom.rb +125 -0
- data/lib/write_xlsx/package/packager.rb +26 -0
- data/lib/write_xlsx/package/styles.rb +53 -21
- data/lib/write_xlsx/package/table.rb +16 -4
- data/lib/write_xlsx/shape.rb +4 -3
- data/lib/write_xlsx/sheets.rb +11 -1
- data/lib/write_xlsx/sparkline.rb +1 -1
- data/lib/write_xlsx/utility.rb +305 -35
- data/lib/write_xlsx/version.rb +1 -1
- data/lib/write_xlsx/workbook.rb +132 -12
- data/lib/write_xlsx/worksheet.rb +397 -163
- data/lib/write_xlsx/worksheet/data_validation.rb +10 -14
- data/lib/write_xlsx/worksheet/hyperlink.rb +4 -13
- data/test/chart/test_write_legend_pos.rb +9 -1
- data/test/chartsheet/test_write_sheet_protection.rb +91 -0
- data/test/drawing/test_drawing_chart_01.rb +6 -2
- data/test/drawing/test_drawing_image_01.rb +12 -3
- data/test/drawing/test_drawing_shape_01.rb +8 -5
- data/test/drawing/test_drawing_shape_02.rb +12 -5
- data/test/drawing/test_drawing_shape_03.rb +8 -5
- data/test/drawing/test_drawing_shape_04.rb +8 -24
- data/test/drawing/test_drawing_shape_05.rb +8 -5
- data/test/drawing/test_drawing_shape_06.rb +11 -6
- data/test/drawing/test_drawing_shape_07.rb +11 -6
- data/test/drawing/test_write_a_graphic_frame_locks.rb +1 -1
- data/test/drawing/test_write_c_chart.rb +1 -1
- data/test/drawing/test_write_c_nv_graphic_frame_pr.rb +1 -1
- data/test/drawing/test_write_c_nv_pr.rb +1 -1
- data/test/drawing/test_write_col.rb +1 -1
- data/test/drawing/test_write_col_off.rb +1 -1
- data/test/drawing/test_write_ext.rb +1 -1
- data/test/drawing/test_write_pos.rb +1 -1
- data/test/drawing/test_write_row.rb +1 -1
- data/test/drawing/test_write_row_off.rb +1 -1
- data/test/drawing/test_write_xfrm_extension.rb +1 -1
- data/test/drawing/test_write_xfrm_offset.rb +1 -1
- data/test/helper.rb +6 -1
- data/test/package/comments/test_comments_01.rb +54 -0
- data/test/package/comments/test_comments_02.rb +54 -0
- data/test/perl_output/chart_gauge.xlsx +0 -0
- data/test/perl_output/formats.xlsx +0 -0
- data/test/regression/_test_hyperlink31.rb +26 -0
- data/test/regression/images/happy.jpg +0 -0
- data/test/regression/images/zero_dpi.jpg +0 -0
- data/test/regression/test_array_formula03.rb +36 -0
- data/test/regression/test_autofilter08.rb +110 -0
- data/test/regression/test_autofilter09.rb +110 -0
- data/test/regression/test_autofilter10.rb +110 -0
- data/test/regression/test_chart_axis26.rb +10 -8
- data/test/regression/test_chart_axis27.rb +1 -1
- data/test/regression/test_chart_axis28.rb +1 -1
- data/test/regression/test_chart_axis29.rb +1 -1
- data/test/regression/test_chart_axis33.rb +1 -1
- data/test/regression/test_chart_axis42.rb +44 -0
- data/test/regression/test_chart_axis43.rb +44 -0
- data/test/regression/test_chart_axis44.rb +54 -0
- data/test/regression/test_chart_axis45.rb +54 -0
- data/test/regression/test_chart_axis46.rb +54 -0
- data/test/regression/test_chart_bar08.rb +3 -0
- data/test/regression/test_chart_bar11.rb +3 -0
- data/test/regression/test_chart_bar14.rb +3 -0
- data/test/regression/test_chart_chartarea05.rb +16 -17
- data/test/regression/test_chart_chartarea06.rb +49 -0
- data/test/regression/test_chart_combined10.rb +43 -0
- data/test/regression/test_chart_combined11.rb +63 -0
- data/test/regression/test_chart_data_labels25.rb +61 -0
- data/test/regression/test_chart_doughnut07.rb +37 -0
- data/test/regression/test_chart_font09.rb +1 -1
- data/test/regression/test_chart_format26.rb +48 -0
- data/test/regression/test_chart_format27.rb +58 -0
- data/test/regression/test_chart_format28.rb +52 -0
- data/test/regression/test_chart_format29.rb +59 -0
- data/test/regression/test_chart_format30.rb +53 -0
- data/test/regression/test_chart_format31.rb +60 -0
- data/test/regression/test_chart_legend03.rb +41 -0
- data/test/regression/test_chart_legend04.rb +41 -0
- data/test/regression/test_chart_legend05.rb +41 -0
- data/test/regression/test_chart_legend06.rb +41 -0
- data/test/regression/test_chart_legend07.rb +38 -0
- data/test/regression/test_chart_size03.rb +4 -1
- data/test/regression/test_chart_table03.rb +56 -0
- data/test/regression/test_comment13.rb +36 -0
- data/test/regression/test_comment14.rb +29 -0
- data/test/regression/test_cond_format14.rb +42 -0
- data/test/regression/test_cond_format15.rb +53 -0
- data/test/regression/test_cond_format16.rb +53 -0
- data/test/regression/test_cond_format17.rb +37 -0
- data/test/regression/test_cond_format18.rb +136 -0
- data/test/regression/test_cond_format19.rb +64 -0
- data/test/regression/test_cond_format20.rb +43 -0
- data/test/regression/test_date_1904_01.rb +1 -1
- data/test/regression/test_escapes04.rb +3 -0
- data/test/regression/test_escapes05.rb +3 -0
- data/test/regression/test_escapes07.rb +3 -0
- data/test/regression/test_escapes08.rb +3 -0
- data/test/regression/test_format15.rb +26 -0
- data/test/regression/test_hyperlink01.rb +3 -0
- data/test/regression/test_hyperlink02.rb +3 -0
- data/test/regression/test_hyperlink03.rb +4 -0
- data/test/regression/test_hyperlink04.rb +3 -0
- data/test/regression/test_hyperlink05.rb +3 -0
- data/test/regression/test_hyperlink06.rb +3 -0
- data/test/regression/test_hyperlink07.rb +3 -0
- data/test/regression/test_hyperlink08.rb +3 -0
- data/test/regression/test_hyperlink09.rb +3 -0
- data/test/regression/test_hyperlink10.rb +3 -0
- data/test/regression/test_hyperlink11.rb +3 -0
- data/test/regression/test_hyperlink12.rb +3 -0
- data/test/regression/test_hyperlink13.rb +3 -0
- data/test/regression/test_hyperlink14.rb +3 -0
- data/test/regression/test_hyperlink15.rb +3 -0
- data/test/regression/test_hyperlink16.rb +3 -0
- data/test/regression/test_hyperlink17.rb +3 -0
- data/test/regression/test_hyperlink18.rb +3 -0
- data/test/regression/test_hyperlink20.rb +3 -0
- data/test/regression/test_hyperlink21.rb +3 -0
- data/test/regression/test_hyperlink22.rb +3 -0
- data/test/regression/test_hyperlink23.rb +3 -0
- data/test/regression/test_hyperlink24.rb +3 -0
- data/test/regression/test_hyperlink25.rb +3 -0
- data/test/regression/test_hyperlink26.rb +3 -0
- data/test/regression/test_hyperlink27.rb +27 -0
- data/test/regression/test_hyperlink28.rb +50 -0
- data/test/regression/test_hyperlink29.rb +27 -0
- data/test/regression/test_hyperlink30.rb +36 -0
- data/test/regression/test_image08.rb +5 -4
- data/test/regression/test_image15.rb +4 -2
- data/test/regression/test_image28.rb +1 -1
- data/test/regression/test_image35.rb +26 -0
- data/test/regression/test_image36.rb +26 -0
- data/test/regression/test_image44.rb +28 -0
- data/test/regression/test_image45.rb +28 -0
- data/test/regression/test_image46.rb +29 -0
- data/test/regression/test_image47.rb +28 -0
- data/test/regression/test_object_position01.rb +26 -0
- data/test/regression/test_object_position02.rb +26 -0
- data/test/regression/test_object_position03.rb +26 -0
- data/test/regression/test_object_position04.rb +44 -0
- data/test/regression/test_object_position06.rb +28 -0
- data/test/regression/test_object_position07.rb +28 -0
- data/test/regression/test_object_position08.rb +47 -0
- data/test/regression/test_object_position09.rb +50 -0
- data/test/regression/test_object_position10.rb +28 -0
- data/test/regression/test_properties01.rb +1 -4
- data/test/regression/test_properties02.rb +1 -4
- data/test/regression/test_properties03.rb +26 -0
- data/test/regression/test_properties04.rb +61 -0
- data/test/regression/test_properties05.rb +30 -0
- data/test/regression/test_shape_connect01.rb +4 -2
- data/test/regression/test_table03.rb +3 -0
- data/test/regression/test_table04.rb +3 -0
- data/test/regression/test_table05.rb +3 -0
- data/test/regression/test_table06.rb +3 -0
- data/test/regression/test_table20.rb +34 -0
- data/test/regression/test_table21.rb +36 -0
- data/test/regression/test_table22.rb +32 -0
- data/test/regression/test_table23.rb +56 -0
- data/test/regression/test_utf8_11.rb +23 -0
- data/test/regression/xlsx_files/array_formula03.xlsx +0 -0
- data/test/regression/xlsx_files/autofilter08.xlsx +0 -0
- data/test/regression/xlsx_files/autofilter09.xlsx +0 -0
- data/test/regression/xlsx_files/autofilter10.xlsx +0 -0
- data/test/regression/xlsx_files/chart_axis26.xlsx +0 -0
- data/test/regression/xlsx_files/chart_axis27.xlsx +0 -0
- data/test/regression/xlsx_files/chart_axis28.xlsx +0 -0
- data/test/regression/xlsx_files/chart_axis29.xlsx +0 -0
- data/test/regression/xlsx_files/chart_axis33.xlsx +0 -0
- data/test/regression/xlsx_files/chart_axis42.xlsx +0 -0
- data/test/regression/xlsx_files/chart_axis43.xlsx +0 -0
- data/test/regression/xlsx_files/chart_axis44.xlsx +0 -0
- data/test/regression/xlsx_files/chart_axis45.xlsx +0 -0
- data/test/regression/xlsx_files/chart_axis46.xlsx +0 -0
- data/test/regression/xlsx_files/chart_chartarea05.xlsx +0 -0
- data/test/regression/xlsx_files/chart_chartarea06.xlsx +0 -0
- data/test/regression/xlsx_files/chart_combined10.xlsx +0 -0
- data/test/regression/xlsx_files/chart_combined11.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels25.xlsx +0 -0
- data/test/regression/xlsx_files/chart_doughnut07.xlsx +0 -0
- data/test/regression/xlsx_files/chart_font09.xlsx +0 -0
- data/test/regression/xlsx_files/chart_format26.xlsx +0 -0
- data/test/regression/xlsx_files/chart_format27.xlsx +0 -0
- data/test/regression/xlsx_files/chart_format28.xlsx +0 -0
- data/test/regression/xlsx_files/chart_format29.xlsx +0 -0
- data/test/regression/xlsx_files/chart_format30.xlsx +0 -0
- data/test/regression/xlsx_files/chart_format31.xlsx +0 -0
- data/test/regression/xlsx_files/chart_legend03.xlsx +0 -0
- data/test/regression/xlsx_files/chart_legend04.xlsx +0 -0
- data/test/regression/xlsx_files/chart_legend05.xlsx +0 -0
- data/test/regression/xlsx_files/chart_legend06.xlsx +0 -0
- data/test/regression/xlsx_files/chart_legend07.xlsx +0 -0
- data/test/regression/xlsx_files/chart_table03.xlsx +0 -0
- data/test/regression/xlsx_files/comment13.xlsx +0 -0
- data/test/regression/xlsx_files/comment14.xlsx +0 -0
- data/test/regression/xlsx_files/cond_format14.xlsx +0 -0
- data/test/regression/xlsx_files/cond_format15.xlsx +0 -0
- data/test/regression/xlsx_files/cond_format16.xlsx +0 -0
- data/test/regression/xlsx_files/cond_format17.xlsx +0 -0
- data/test/regression/xlsx_files/cond_format18.xlsx +0 -0
- data/test/regression/xlsx_files/cond_format19.xlsx +0 -0
- data/test/regression/xlsx_files/cond_format20.xlsx +0 -0
- data/test/regression/xlsx_files/date_1904_01.xlsx +0 -0
- data/test/regression/xlsx_files/format15.xlsx +0 -0
- data/test/regression/xlsx_files/hyperlink27.xlsx +0 -0
- data/test/regression/xlsx_files/hyperlink28.xlsx +0 -0
- data/test/regression/xlsx_files/hyperlink29.xlsx +0 -0
- data/test/regression/xlsx_files/hyperlink30.xlsx +0 -0
- data/test/regression/xlsx_files/hyperlink31.xlsx +0 -0
- data/test/regression/xlsx_files/image35.xlsx +0 -0
- data/test/regression/xlsx_files/image36.xlsx +0 -0
- data/test/regression/xlsx_files/image44.xlsx +0 -0
- data/test/regression/xlsx_files/image45.xlsx +0 -0
- data/test/regression/xlsx_files/image46.xlsx +0 -0
- data/test/regression/xlsx_files/image47.xlsx +0 -0
- data/test/regression/xlsx_files/object_position01.xlsx +0 -0
- data/test/regression/xlsx_files/object_position02.xlsx +0 -0
- data/test/regression/xlsx_files/object_position03.xlsx +0 -0
- data/test/regression/xlsx_files/object_position04.xlsx +0 -0
- data/test/regression/xlsx_files/object_position06.xlsx +0 -0
- data/test/regression/xlsx_files/object_position07.xlsx +0 -0
- data/test/regression/xlsx_files/object_position08.xlsx +0 -0
- data/test/regression/xlsx_files/object_position09.xlsx +0 -0
- data/test/regression/xlsx_files/object_position10.xlsx +0 -0
- data/test/regression/xlsx_files/properties03.xlsx +0 -0
- data/test/regression/xlsx_files/properties04.xlsx +0 -0
- data/test/regression/xlsx_files/properties05.xlsx +0 -0
- data/test/regression/xlsx_files/table21.xlsx +0 -0
- data/test/regression/xlsx_files/table22.xlsx +0 -0
- data/test/regression/xlsx_files/table23.xlsx +0 -0
- data/test/regression/xlsx_files/utf8_11.xlsx +0 -0
- data/test/test_example_match.rb +836 -771
- data/test/workbook/test_check_sheetname.rb +61 -0
- data/test/workbook/test_worksheet_by_name.rb +35 -0
- data/test/workbook/test_write_workbook_view.rb +117 -0
- data/test/worksheet/test_cond_format_22.rb +266 -0
- data/test/worksheet/test_cond_format_23.rb +242 -0
- data/test/worksheet/test_cond_format_24.rb +303 -0
- data/test/worksheet/test_data_bar_01.rb +53 -0
- data/test/worksheet/test_data_bar_02.rb +79 -0
- data/test/worksheet/test_data_bar_03.rb +147 -0
- data/test/worksheet/test_data_bar_04.rb +145 -0
- data/test/worksheet/test_data_bar_05.rb +147 -0
- data/test/worksheet/test_data_bar_06.rb +145 -0
- data/test/worksheet/test_data_bar_07.rb +146 -0
- data/test/worksheet/test_data_bar_08.rb +54 -0
- data/test/worksheet/test_data_bar_09.rb +80 -0
- data/test/worksheet/test_data_bar_10.rb +165 -0
- data/test/worksheet/test_data_bar_11.rb +167 -0
- data/test/worksheet/test_data_bar_12.rb +104 -0
- data/test/worksheet/test_write_data_validation_02.rb +44 -0
- data/test/worksheet/test_write_hyperlink.rb +0 -7
- data/test/worksheet/test_write_sheet_view.rb +19 -1
- metadata +308 -5
- data/test/package/comments/test_write_text_t.rb +0 -44
data/lib/write_xlsx/sheets.rb
CHANGED
@@ -230,10 +230,20 @@ def check_valid_sheetname(name)
|
|
230
230
|
raise 'Invalid character []:*?/\\ in worksheet name: ' + name
|
231
231
|
end
|
232
232
|
|
233
|
+
# Check that sheetname doesn't start or end with an apostrophe.
|
234
|
+
if name =~ /^'/ || name =~ /'$/
|
235
|
+
raise "Worksheet name #{name} cannot start or end with an "
|
236
|
+
end
|
237
|
+
|
238
|
+
# Check that sheetname isn't a reserved word.
|
239
|
+
if name =~ /history/i
|
240
|
+
raise "Worksheet name cannot be Excel reserved word 'History'"
|
241
|
+
end
|
242
|
+
|
233
243
|
# Check that the worksheet name doesn't already exist since this is a fatal
|
234
244
|
# error in Excel 97. The check must also exclude case insensitive matches.
|
235
245
|
unless is_sheetname_uniq?(name)
|
236
|
-
raise "
|
246
|
+
raise "apostropheWorksheet name '#{name}', with case ignored, is already used."
|
237
247
|
end
|
238
248
|
end
|
239
249
|
|
data/lib/write_xlsx/sparkline.rb
CHANGED
@@ -9,7 +9,7 @@ module Writexlsx
|
|
9
9
|
# Used in conjunction with WriteXLSX.
|
10
10
|
#
|
11
11
|
# Copyright 2000-2012, John McNamara, jmcnamara@cpan.org
|
12
|
-
# Converted to ruby by Hideo NAKAMURA,
|
12
|
+
# Converted to ruby by Hideo NAKAMURA, nakamura.hideo@gmail.com
|
13
13
|
#
|
14
14
|
class Sparkline
|
15
15
|
include Writexlsx::Utility
|
data/lib/write_xlsx/utility.rb
CHANGED
@@ -119,7 +119,7 @@ def check_dimensions(row, col)
|
|
119
119
|
# nil if the date is invalid.
|
120
120
|
#
|
121
121
|
def convert_date_time(date_time_string) #:nodoc:
|
122
|
-
date_time = date_time_string.sub(/^\s+/, '').sub(/\s+$/, '').sub(/Z$/, '')
|
122
|
+
date_time = date_time_string.to_s.sub(/^\s+/, '').sub(/\s+$/, '').sub(/Z$/, '')
|
123
123
|
|
124
124
|
# Check for invalid date char.
|
125
125
|
return nil if date_time =~ /[^0-9T:\-\.Z]/
|
@@ -320,7 +320,7 @@ def check_parameter(params, valid_keys, method)
|
|
320
320
|
invalids = params.keys - valid_keys
|
321
321
|
unless invalids.empty?
|
322
322
|
raise WriteXLSXOptionParameterError,
|
323
|
-
|
323
|
+
"Unknown parameter '#{invalids.join(', ')}' in #{method}."
|
324
324
|
end
|
325
325
|
true
|
326
326
|
end
|
@@ -361,6 +361,64 @@ def float_to_str(float)
|
|
361
361
|
end
|
362
362
|
end
|
363
363
|
|
364
|
+
#
|
365
|
+
# Convert user defined legend properties to the structure required internally.
|
366
|
+
#
|
367
|
+
def legend_properties(params)
|
368
|
+
legend = Writexlsx::Chart::Legend.new
|
369
|
+
|
370
|
+
legend.position = params[:position] || 'right'
|
371
|
+
legend.delete_series = params[:delete_series]
|
372
|
+
legend.font = convert_font_args(params[:font])
|
373
|
+
|
374
|
+
# Set the legend layout.
|
375
|
+
legend.layout = layout_properties(params[:layout])
|
376
|
+
|
377
|
+
# Turn off the legend.
|
378
|
+
if params[:none]
|
379
|
+
legend.position = 'none'
|
380
|
+
end
|
381
|
+
|
382
|
+
# Set the line properties for the legend.
|
383
|
+
line = line_properties(params[:line])
|
384
|
+
|
385
|
+
# Allow 'border' as a synonym for 'line'.
|
386
|
+
if params[:border]
|
387
|
+
line = line_properties(params[:border])
|
388
|
+
end
|
389
|
+
|
390
|
+
# Set the fill properties for the legend.
|
391
|
+
fill = fill_properties(params[:fill])
|
392
|
+
|
393
|
+
# Set the pattern properties for the legend.
|
394
|
+
pattern = pattern_properties(params[:pattern])
|
395
|
+
|
396
|
+
# Set the gradient fill properties for the legend.
|
397
|
+
gradient = gradient_properties(params[:gradient])
|
398
|
+
|
399
|
+
# Pattern fill overrides solid fill.
|
400
|
+
if pattern
|
401
|
+
fill = nil
|
402
|
+
end
|
403
|
+
|
404
|
+
# Gradient fill overrides solid and pattern fills.
|
405
|
+
if gradient
|
406
|
+
pattern = nil
|
407
|
+
fill = nil
|
408
|
+
end
|
409
|
+
|
410
|
+
# Set the legend layout.
|
411
|
+
layout = layout_properties(params[:layout])
|
412
|
+
|
413
|
+
legend.line = line
|
414
|
+
legend.fill = fill
|
415
|
+
legend.pattern = pattern
|
416
|
+
legend.gradient = gradient
|
417
|
+
legend.layout = layout
|
418
|
+
|
419
|
+
@legend = legend
|
420
|
+
end
|
421
|
+
|
364
422
|
#
|
365
423
|
# Convert user defined layout properties to the format required internally.
|
366
424
|
#
|
@@ -372,7 +430,7 @@ def layout_properties(args, is_text = false)
|
|
372
430
|
# Check for valid properties.
|
373
431
|
args.keys.each do |key|
|
374
432
|
unless properties.include?(key.to_sym)
|
375
|
-
|
433
|
+
raise "Property '#{key}' not allowed in layout options\n"
|
376
434
|
end
|
377
435
|
end
|
378
436
|
|
@@ -405,9 +463,9 @@ def pixels_to_points(vertices)
|
|
405
463
|
|
406
464
|
def v_shape_attributes_base(id, z_index)
|
407
465
|
[
|
408
|
-
|
409
|
-
|
410
|
-
|
466
|
+
['id', "_x0000_s#{id}"],
|
467
|
+
['type', type],
|
468
|
+
['style', (v_shape_style_base(z_index, vertices) + style_addition).join]
|
411
469
|
]
|
412
470
|
end
|
413
471
|
|
@@ -425,17 +483,17 @@ def v_shape_style_base(z_index, vertices)
|
|
425
483
|
|
426
484
|
def shape_style_base(left_str, top_str, width_str, height_str, z_index_str)
|
427
485
|
[
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
486
|
+
'position:absolute;',
|
487
|
+
'margin-left:',
|
488
|
+
left_str, 'pt;',
|
489
|
+
'margin-top:',
|
490
|
+
top_str, 'pt;',
|
491
|
+
'width:',
|
492
|
+
width_str, 'pt;',
|
493
|
+
'height:',
|
494
|
+
height_str, 'pt;',
|
495
|
+
'z-index:',
|
496
|
+
z_index_str, ';'
|
439
497
|
]
|
440
498
|
end
|
441
499
|
|
@@ -500,10 +558,10 @@ def write_font(font)
|
|
500
558
|
color = '#000000'
|
501
559
|
|
502
560
|
attributes = [
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
561
|
+
['face', face],
|
562
|
+
['size', size],
|
563
|
+
['color', color]
|
564
|
+
]
|
507
565
|
@writer.data_element('font', caption, attributes)
|
508
566
|
end
|
509
567
|
|
@@ -612,7 +670,7 @@ def pattern_properties(args) # :nodoc:
|
|
612
670
|
'small_check' => 'smCheck',
|
613
671
|
'large_check' => 'lgCheck',
|
614
672
|
'outlined_diamond' => 'openDmnd',
|
615
|
-
'solid_diamond' => 'solidDmnd'
|
673
|
+
'solid_diamond' => 'solidDmnd'
|
616
674
|
}
|
617
675
|
|
618
676
|
# Check for valid types.
|
@@ -627,7 +685,7 @@ def pattern_properties(args) # :nodoc:
|
|
627
685
|
|
628
686
|
pattern
|
629
687
|
end
|
630
|
-
|
688
|
+
|
631
689
|
def line_fill_properties(params)
|
632
690
|
return { :_defined => 0 } unless params
|
633
691
|
ret = params.dup
|
@@ -690,22 +748,234 @@ def process_workbook_options(*params)
|
|
690
748
|
[options.dup, default_format_properties.dup]
|
691
749
|
end
|
692
750
|
end
|
751
|
+
|
752
|
+
#
|
753
|
+
# Convert user defined font values into private hash values.
|
754
|
+
#
|
755
|
+
def convert_font_args(params)
|
756
|
+
return unless params
|
757
|
+
font = params_to_font(params)
|
758
|
+
|
759
|
+
# Convert font size units.
|
760
|
+
font[:_size] *= 100 if font[:_size] && font[:_size] != 0
|
761
|
+
|
762
|
+
# Convert rotation into 60,000ths of a degree.
|
763
|
+
if ptrue?(font[:_rotation])
|
764
|
+
font[:_rotation] = 60_000 * font[:_rotation].to_i
|
765
|
+
end
|
766
|
+
|
767
|
+
font
|
768
|
+
end
|
769
|
+
|
770
|
+
def params_to_font(params)
|
771
|
+
{
|
772
|
+
:_name => params[:name],
|
773
|
+
:_color => params[:color],
|
774
|
+
:_size => params[:size],
|
775
|
+
:_bold => params[:bold],
|
776
|
+
:_italic => params[:italic],
|
777
|
+
:_underline => params[:underline],
|
778
|
+
:_pitch_family => params[:pitch_family],
|
779
|
+
:_charset => params[:charset],
|
780
|
+
:_baseline => params[:baseline] || 0,
|
781
|
+
:_rotation => params[:rotation]
|
782
|
+
}
|
783
|
+
end
|
784
|
+
|
785
|
+
#
|
786
|
+
# Write the <c:txPr> element.
|
787
|
+
#
|
788
|
+
def write_tx_pr(is_y_axis, font) # :nodoc:
|
789
|
+
rotation = nil
|
790
|
+
if font && font[:_rotation]
|
791
|
+
rotation = font[:_rotation]
|
792
|
+
end
|
793
|
+
@writer.tag_elements('c:txPr') do
|
794
|
+
# Write the a:bodyPr element.
|
795
|
+
write_a_body_pr(rotation, is_y_axis)
|
796
|
+
# Write the a:lstStyle element.
|
797
|
+
write_a_lst_style
|
798
|
+
# Write the a:p element.
|
799
|
+
write_a_p_formula(font)
|
800
|
+
end
|
801
|
+
end
|
802
|
+
|
803
|
+
#
|
804
|
+
# Write the <a:bodyPr> element.
|
805
|
+
#
|
806
|
+
def write_a_body_pr(rot, is_y_axis = nil) # :nodoc:
|
807
|
+
rot = -5400000 if !rot && ptrue?(is_y_axis)
|
808
|
+
attributes = []
|
809
|
+
if rot
|
810
|
+
if rot == 16_200_000
|
811
|
+
# 270 deg/stacked angle.
|
812
|
+
attributes << ['rot', 0]
|
813
|
+
attributes << ['vert', 'wordArtVert']
|
814
|
+
elsif rot == 16_260_000
|
815
|
+
# 271 deg/stacked angle.
|
816
|
+
attributes << ['rot', 0]
|
817
|
+
attributes << ['vert', 'eaVert']
|
818
|
+
else
|
819
|
+
attributes << ['rot', rot]
|
820
|
+
attributes << ['vert', 'horz']
|
821
|
+
end
|
822
|
+
end
|
823
|
+
|
824
|
+
@writer.empty_tag('a:bodyPr', attributes)
|
825
|
+
end
|
826
|
+
|
827
|
+
#
|
828
|
+
# Write the <a:lstStyle> element.
|
829
|
+
#
|
830
|
+
def write_a_lst_style # :nodoc:
|
831
|
+
@writer.empty_tag('a:lstStyle')
|
832
|
+
end
|
833
|
+
|
834
|
+
#
|
835
|
+
# Write the <a:p> element for formula titles.
|
836
|
+
#
|
837
|
+
def write_a_p_formula(font = nil) # :nodoc:
|
838
|
+
@writer.tag_elements('a:p') do
|
839
|
+
# Write the a:pPr element.
|
840
|
+
write_a_p_pr_formula(font)
|
841
|
+
# Write the a:endParaRPr element.
|
842
|
+
write_a_end_para_rpr
|
843
|
+
end
|
844
|
+
end
|
845
|
+
|
846
|
+
#
|
847
|
+
# Write the <a:pPr> element for formula titles.
|
848
|
+
#
|
849
|
+
def write_a_p_pr_formula(font) # :nodoc:
|
850
|
+
@writer.tag_elements('a:pPr') { write_a_def_rpr(font) }
|
851
|
+
end
|
852
|
+
|
853
|
+
#
|
854
|
+
# Write the <a:defRPr> element.
|
855
|
+
#
|
856
|
+
def write_a_def_rpr(font = nil) # :nodoc:
|
857
|
+
write_def_rpr_r_pr_common(
|
858
|
+
font,
|
859
|
+
get_font_style_attributes(font),
|
860
|
+
'a:defRPr'
|
861
|
+
)
|
862
|
+
end
|
863
|
+
|
864
|
+
def write_def_rpr_r_pr_common(font, style_attributes, tag) # :nodoc:
|
865
|
+
latin_attributes = get_font_latin_attributes(font)
|
866
|
+
has_color = ptrue?(font) && ptrue?(font[:_color])
|
867
|
+
|
868
|
+
if !latin_attributes.empty? || has_color
|
869
|
+
@writer.tag_elements(tag, style_attributes) do
|
870
|
+
if has_color
|
871
|
+
write_a_solid_fill(:color => font[:_color])
|
872
|
+
end
|
873
|
+
if !latin_attributes.empty?
|
874
|
+
write_a_latin(latin_attributes)
|
875
|
+
end
|
876
|
+
end
|
877
|
+
else
|
878
|
+
@writer.empty_tag(tag, style_attributes)
|
879
|
+
end
|
880
|
+
end
|
881
|
+
|
882
|
+
#
|
883
|
+
# Get the font latin attributes from a font hash.
|
884
|
+
#
|
885
|
+
def get_font_latin_attributes(font)
|
886
|
+
return [] unless font
|
887
|
+
|
888
|
+
attributes = []
|
889
|
+
attributes << ['typeface', font[:_name]] if ptrue?(font[:_name])
|
890
|
+
attributes << ['pitchFamily', font[:_pitch_family]] if font[:_pitch_family]
|
891
|
+
attributes << ['charset', font[:_charset]] if font[:_charset]
|
892
|
+
|
893
|
+
attributes
|
894
|
+
end
|
895
|
+
|
896
|
+
#
|
897
|
+
# Write the <a:solidFill> element.
|
898
|
+
#
|
899
|
+
def write_a_solid_fill(fill) # :nodoc:
|
900
|
+
@writer.tag_elements('a:solidFill') do
|
901
|
+
if fill[:color]
|
902
|
+
# Write the a:srgbClr element.
|
903
|
+
write_a_srgb_clr(color(fill[:color]), fill[:transparency])
|
904
|
+
end
|
905
|
+
end
|
906
|
+
end
|
907
|
+
|
908
|
+
#
|
909
|
+
# Write the <a:srgbClr> element.
|
910
|
+
#
|
911
|
+
def write_a_srgb_clr(color, transparency = nil) # :nodoc:
|
912
|
+
tag = 'a:srgbClr'
|
913
|
+
attributes = [ ['val', color] ]
|
914
|
+
|
915
|
+
if ptrue?(transparency)
|
916
|
+
@writer.tag_elements(tag, attributes) do
|
917
|
+
write_a_alpha(transparency)
|
918
|
+
end
|
919
|
+
else
|
920
|
+
@writer.empty_tag(tag, attributes)
|
921
|
+
end
|
922
|
+
end
|
923
|
+
|
924
|
+
#
|
925
|
+
# Convert the user specified colour index or string to a rgb colour.
|
926
|
+
#
|
927
|
+
def color(color_code) # :nodoc:
|
928
|
+
if color_code and color_code =~ /^#[0-9a-fA-F]{6}$/
|
929
|
+
# Convert a HTML style #RRGGBB color.
|
930
|
+
color_code.sub(/^#/, '').upcase
|
931
|
+
else
|
932
|
+
index = Format.color(color_code)
|
933
|
+
raise "Unknown color '#{color_code}' used in chart formatting." unless index
|
934
|
+
palette_color(index)
|
935
|
+
end
|
936
|
+
end
|
937
|
+
|
938
|
+
#
|
939
|
+
# Get the font style attributes from a font hash.
|
940
|
+
#
|
941
|
+
def get_font_style_attributes(font)
|
942
|
+
return [] unless font
|
943
|
+
|
944
|
+
attributes = []
|
945
|
+
attributes << ['sz', font[:_size]] if ptrue?(font[:_size])
|
946
|
+
attributes << ['b', font[:_bold]] if font[:_bold]
|
947
|
+
attributes << ['i', font[:_italic]] if font[:_italic]
|
948
|
+
attributes << ['u', 'sng'] if font[:_underline]
|
949
|
+
|
950
|
+
# Turn off baseline when testing fonts that don't have it.
|
951
|
+
if font[:_baseline] != -1
|
952
|
+
attributes << ['baseline', font[:_baseline]]
|
953
|
+
end
|
954
|
+
attributes
|
955
|
+
end
|
956
|
+
|
957
|
+
#
|
958
|
+
# Write the <a:endParaRPr> element.
|
959
|
+
#
|
960
|
+
def write_a_end_para_rpr # :nodoc:
|
961
|
+
@writer.empty_tag('a:endParaRPr', [ ['lang', 'en-US'] ])
|
962
|
+
end
|
693
963
|
end
|
694
964
|
|
695
965
|
module WriteDPtPoint
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
end
|
966
|
+
#
|
967
|
+
# Write an individual <c:dPt> element. Override the parent method to add
|
968
|
+
# markers.
|
969
|
+
#
|
970
|
+
def write_d_pt_point(index, point)
|
971
|
+
@writer.tag_elements('c:dPt') do
|
972
|
+
# Write the c:idx element.
|
973
|
+
write_idx(index)
|
974
|
+
@writer.tag_elements('c:marker') do
|
975
|
+
# Write the c:spPr element.
|
976
|
+
write_sp_pr(point)
|
708
977
|
end
|
709
978
|
end
|
979
|
+
end
|
710
980
|
end
|
711
981
|
end
|
data/lib/write_xlsx/version.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
WriteXLSX_VERSION = "
|
1
|
+
WriteXLSX_VERSION = "1.01.0"
|
data/lib/write_xlsx/workbook.rb
CHANGED
@@ -44,11 +44,14 @@ class Workbook
|
|
44
44
|
attr_reader :worksheets, :charts, :drawings # :nodoc:
|
45
45
|
attr_reader :named_ranges # :nodoc:
|
46
46
|
attr_reader :doc_properties # :nodoc:
|
47
|
+
attr_reader :custom_properties # :nodoc:
|
47
48
|
attr_reader :image_types, :images # :nodoc:
|
48
49
|
attr_reader :shared_strings # :nodoc:
|
49
50
|
attr_reader :vba_project # :nodoc:
|
50
51
|
attr_reader :excel2003_style # :nodoc:
|
51
52
|
attr_reader :strings_to_urls # :nodoc:
|
53
|
+
attr_reader :default_url_format # :nodoc:
|
54
|
+
|
52
55
|
#
|
53
56
|
# A new Excel workbook is created using the +new+ constructor
|
54
57
|
# which accepts either a filename or an IO object as a parameter.
|
@@ -114,13 +117,13 @@ def initialize(file, *option_params)
|
|
114
117
|
@named_ranges = []
|
115
118
|
@custom_colors = []
|
116
119
|
@doc_properties = {}
|
117
|
-
@
|
120
|
+
@custom_properties = []
|
118
121
|
@optimization = options[:optimization] || 0
|
119
122
|
@x_window = 240
|
120
123
|
@y_window = 15
|
121
124
|
@window_width = 16095
|
122
125
|
@window_height = 9660
|
123
|
-
@tab_ratio =
|
126
|
+
@tab_ratio = 600
|
124
127
|
@excel2003_style = options[:excel2003_style] || false
|
125
128
|
@table_count = 0
|
126
129
|
@image_types = {}
|
@@ -141,6 +144,10 @@ def initialize(file, *option_params)
|
|
141
144
|
else
|
142
145
|
add_format(default_formats.merge(:xf_index => 0))
|
143
146
|
end
|
147
|
+
|
148
|
+
# Add a default URL format.
|
149
|
+
@default_url_format = add_format(:hyperlink => 1)
|
150
|
+
|
144
151
|
set_color_palette
|
145
152
|
end
|
146
153
|
|
@@ -203,6 +210,14 @@ def sheets(*args)
|
|
203
210
|
end
|
204
211
|
end
|
205
212
|
|
213
|
+
#
|
214
|
+
# Return a worksheet object in the workbook using the sheetname.
|
215
|
+
#
|
216
|
+
def worksheet_by_name(sheetname = nil)
|
217
|
+
sheets.select { |s| s.name == sheetname }.first
|
218
|
+
end
|
219
|
+
alias get_worksheet_by_name worksheet_by_name
|
220
|
+
|
206
221
|
#
|
207
222
|
# Set the date system: false = 1900 (the default), true = 1904
|
208
223
|
#
|
@@ -750,6 +765,38 @@ def define_name(name, formula)
|
|
750
765
|
@defined_names.push([ name, sheet_index, formula.sub(/^=/, '') ])
|
751
766
|
end
|
752
767
|
|
768
|
+
#
|
769
|
+
# Set the workbook size.
|
770
|
+
#
|
771
|
+
def set_size(width = nil, height = nil)
|
772
|
+
if ptrue?(width)
|
773
|
+
# Convert to twips at 96 dpi.
|
774
|
+
@window_width = width.to_i * 1440 / 96
|
775
|
+
else
|
776
|
+
@window_width = 16095
|
777
|
+
end
|
778
|
+
|
779
|
+
if ptrue?(height)
|
780
|
+
# Convert to twips at 96 dpi.
|
781
|
+
@window_height = height.to_i * 1440 / 96
|
782
|
+
else
|
783
|
+
@window_height = 9660
|
784
|
+
end
|
785
|
+
end
|
786
|
+
|
787
|
+
#
|
788
|
+
# Set the ratio of space for worksheet tabs.
|
789
|
+
#
|
790
|
+
def set_tab_ratio(tab_ratio = nil)
|
791
|
+
return if !tab_ratio
|
792
|
+
|
793
|
+
if tab_ratio < 0 || tab_ratio > 100
|
794
|
+
raise "Tab ratio outside range: 0 <= zoom <= 100"
|
795
|
+
else
|
796
|
+
@tab_ratio = (tab_ratio * 10).to_i
|
797
|
+
end
|
798
|
+
end
|
799
|
+
|
753
800
|
#
|
754
801
|
# The set_properties method can be used to set the document properties
|
755
802
|
# of the Excel file created by WriteXLSX. These properties are visible
|
@@ -806,11 +853,58 @@ def set_properties(params)
|
|
806
853
|
end
|
807
854
|
|
808
855
|
# Set the creation time unless specified by the user.
|
809
|
-
params[:created] = @
|
856
|
+
params[:created] = @createtime unless params.has_key?(:created)
|
810
857
|
|
811
858
|
@doc_properties = params.dup
|
812
859
|
end
|
813
860
|
|
861
|
+
#
|
862
|
+
# Set a user defined custom document property.
|
863
|
+
#
|
864
|
+
def set_custom_property(name, value, type = nil)
|
865
|
+
# Valid types.
|
866
|
+
valid_type = {
|
867
|
+
'text' => 1,
|
868
|
+
'date' => 1,
|
869
|
+
'number' => 1,
|
870
|
+
'number_int' => 1,
|
871
|
+
'bool' => 1,
|
872
|
+
}
|
873
|
+
|
874
|
+
if !name || (type != 'bool' && !value)
|
875
|
+
raise "The name and value parameters must be defined in set_custom_property()"
|
876
|
+
end
|
877
|
+
|
878
|
+
# Determine the type for strings and numbers if it hasn't been specified.
|
879
|
+
if !ptrue?(type)
|
880
|
+
if value =~ /^\d+$/
|
881
|
+
type = 'number_int'
|
882
|
+
elsif value =~
|
883
|
+
/^([+-]?)(?=[0-9]|\.[0-9])[0-9]*(\.[0-9]*)?([Ee]([+-]?[0-9]+))?$/
|
884
|
+
type = 'number'
|
885
|
+
else
|
886
|
+
type = 'text'
|
887
|
+
end
|
888
|
+
end
|
889
|
+
|
890
|
+
# Check for valid validation types.
|
891
|
+
if !valid_type[type]
|
892
|
+
raise "Unknown custom type '$type' in set_custom_property()"
|
893
|
+
end
|
894
|
+
|
895
|
+
# Check for strings longer than Excel's limit of 255 chars.
|
896
|
+
if type == 'text' && value.length > 255
|
897
|
+
raise "Length of text custom value '$value' exceeds Excel's limit of 255 in set_custom_property()"
|
898
|
+
end
|
899
|
+
|
900
|
+
if type == 'bool'
|
901
|
+
value = value ? 1 : 0
|
902
|
+
end
|
903
|
+
|
904
|
+
@custom_properties << [name, value, type]
|
905
|
+
end
|
906
|
+
|
907
|
+
|
814
908
|
#
|
815
909
|
# The add_vba_project method can be used to add macros or functions to an
|
816
910
|
# WriteXLSX file using a binary VBA project file that has been extracted
|
@@ -869,6 +963,16 @@ def set_calc_mode(mode, calc_id = nil)
|
|
869
963
|
@calc_id = calc_id if calc_id
|
870
964
|
end
|
871
965
|
|
966
|
+
#
|
967
|
+
# Get the default url format used when a user defined format isn't specified
|
968
|
+
# with write_url(). The format is the hyperlink style defined by Excel for the
|
969
|
+
# default theme.
|
970
|
+
#
|
971
|
+
def default_url_format
|
972
|
+
@default_url_format
|
973
|
+
end
|
974
|
+
alias get_default_url_format default_url_format
|
975
|
+
|
872
976
|
#
|
873
977
|
# Change the RGB components of the elements in the colour palette.
|
874
978
|
#
|
@@ -1217,7 +1321,7 @@ def write_workbook_view #:nodoc:
|
|
1217
1321
|
['windowWidth', @window_width],
|
1218
1322
|
['windowHeight', @window_height]
|
1219
1323
|
]
|
1220
|
-
if @tab_ratio !=
|
1324
|
+
if @tab_ratio != 600
|
1221
1325
|
attributes << ['tabRatio', @tab_ratio]
|
1222
1326
|
end
|
1223
1327
|
if @firstsheet > 0
|
@@ -1421,9 +1525,17 @@ def prepare_num_formats #:nodoc:
|
|
1421
1525
|
# string but would evaluate to zero.
|
1422
1526
|
#
|
1423
1527
|
if num_format.to_s =~ /^\d+$/ && num_format.to_s !~ /^0+\d/
|
1528
|
+
# Number format '0' is indexed as 1 in Excel.
|
1529
|
+
if num_format == 0
|
1530
|
+
num_format = 1
|
1531
|
+
end
|
1424
1532
|
# Index to a built-in number format.
|
1425
1533
|
format.num_format_index = num_format
|
1426
1534
|
next
|
1535
|
+
elsif num_format.to_s == 'General'
|
1536
|
+
# The 'General' format has an number format index of 0.
|
1537
|
+
format.num_format_index = 0
|
1538
|
+
next
|
1427
1539
|
end
|
1428
1540
|
|
1429
1541
|
if num_formats[num_format]
|
@@ -1812,7 +1924,7 @@ def prepare_drawings #:nodoc:
|
|
1812
1924
|
shape_count = sheet.shapes.size
|
1813
1925
|
header_image_count = sheet.header_images.size
|
1814
1926
|
footer_image_count = sheet.footer_images.size
|
1815
|
-
|
1927
|
+
has_drawings = false
|
1816
1928
|
|
1817
1929
|
# Check that some image or drawing needs to be processed.
|
1818
1930
|
next if chart_count + image_count + shape_count + header_image_count + footer_image_count == 0
|
@@ -1820,7 +1932,7 @@ def prepare_drawings #:nodoc:
|
|
1820
1932
|
# Don't increase the drawing_id header/footer images.
|
1821
1933
|
if chart_count + image_count + shape_count > 0
|
1822
1934
|
drawing_id += 1
|
1823
|
-
|
1935
|
+
has_drawings = true
|
1824
1936
|
end
|
1825
1937
|
|
1826
1938
|
# Prepare the worksheet charts.
|
@@ -1869,9 +1981,9 @@ def prepare_drawings #:nodoc:
|
|
1869
1981
|
name, type, position, x_dpi, y_dpi)
|
1870
1982
|
end
|
1871
1983
|
|
1872
|
-
if
|
1873
|
-
|
1874
|
-
@drawings <<
|
1984
|
+
if has_drawings
|
1985
|
+
drawings = sheet.drawings
|
1986
|
+
@drawings << drawings
|
1875
1987
|
end
|
1876
1988
|
end
|
1877
1989
|
|
@@ -1914,6 +2026,10 @@ def get_image_properties(filename)
|
|
1914
2026
|
|
1915
2027
|
@images << [filename, type]
|
1916
2028
|
|
2029
|
+
# Set a default dpi for images with 0 dpi.
|
2030
|
+
x_dpi = 96 if x_dpi == 0
|
2031
|
+
y_dpi = 96 if y_dpi == 0
|
2032
|
+
|
1917
2033
|
[type, width, height, File.basename(filename), x_dpi, y_dpi]
|
1918
2034
|
end
|
1919
2035
|
|
@@ -1969,16 +2085,20 @@ def process_jpg(data, filename)
|
|
1969
2085
|
offset = 2
|
1970
2086
|
data_length = data.bytesize
|
1971
2087
|
|
1972
|
-
# Search through the image data to read the
|
1973
|
-
# 0xFFC0/C2 element. Also read the DPI in the 0xFFE0 element.
|
2088
|
+
# Search through the image data to read the JPEG markers.
|
1974
2089
|
while offset < data_length
|
1975
2090
|
marker = data[offset+0, 2].unpack("n")[0]
|
1976
2091
|
length = data[offset+2, 2].unpack("n")[0]
|
1977
2092
|
|
1978
|
-
|
2093
|
+
# Read the height and width in the 0xFFCn elements
|
2094
|
+
# (Except C4, C8 and CC which aren't SOF markers).
|
2095
|
+
if (marker & 0xFFF0) == 0xFFC0 &&
|
2096
|
+
marker != 0xFFC4 && marker != 0xFFCC
|
1979
2097
|
height = data[offset+5, 2].unpack("n")[0]
|
1980
2098
|
width = data[offset+7, 2].unpack("n")[0]
|
1981
2099
|
end
|
2100
|
+
|
2101
|
+
# Read the DPI in the 0xFFE0 element.
|
1982
2102
|
if marker == 0xFFE0
|
1983
2103
|
units = data[offset + 11, 1].unpack("C")[0]
|
1984
2104
|
x_density = data[offset + 12, 2].unpack("n")[0]
|