Module: Writexlsx::Worksheet::Columns
- Included in:
- Writexlsx::Worksheet
- Defined in:
- lib/write_xlsx/worksheet/columns.rb
Overview
Column-related operations extracted from Worksheet to slim the main class.
Instance Method Summary collapse
-
#autofit(max_width = 255.0) ⇒ Object
autofit().
-
#set_column(*args) ⇒ Object
:call-seq: set_column(firstcol, lastcol, width, format, hidden, level, collapsed).
-
#set_column_pixels(*data) ⇒ Object
Set the width (and properties) of a single column or a range of columns in pixels rather than character units.
Instance Method Details
#autofit(max_width = 255.0) ⇒ Object
autofit()
Simulate autofit based on the data, and datatypes in each column. We do this by estimating a pixel width for each cell data.
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
# File 'lib/write_xlsx/worksheet/columns.rb', line 98 def autofit(max_width = 255.0) col_width = {} # Convert the autofit maximum pixel width to a column/character width, but # limit it to the Excel max limit. max_width = pixels_to_width(max_width) max_width = 255.0 if max_width > 255.0 # Iterate through all the data in the worksheet. (@dim_rowmin..@dim_rowmax).each do |row_num| # Skip row if it doesn't contain cell data. next unless @cell_data_store[row_num] (@dim_colmin..@dim_colmax).each do |col_num| length = 0 case (cell_data = @cell_data_store[row_num][col_num]) when StringCellData, RichStringCellData # Handle strings and rich strings. # # For standard shared strings we do a reverse lookup # from the shared string id to the actual string. For # rich strings we use the unformatted string. We also # split multiline strings and handle each part # separately. string = cell_data.raw_string length = if string =~ /\n/ # Handle multiline strings. max = string.split("\n").collect do |str| xl_string_pixel_width(str) end.max else xl_string_pixel_width(string) end when DateTimeCellData # Handle dates. # # The following uses the default width for mm/dd/yyyy # dates. It isn't feasible to parse the number format # to get the actual string width for all format types. length = @default_date_pixels when NumberCellData # Handle numbers. # # We use a workaround/optimization for numbers since # digits all have a pixel width of 7. This gives a # slightly greater width for the decimal place and # minus sign but only by a few pixels and # over-estimation is okay. length = 7 * cell_data.token.to_s.length when BooleanCellData # Handle boolean values. # # Use the Excel standard widths for TRUE and FALSE. length = if ptrue?(cell_data.token) 31 else 36 end when FormulaCellData, FormulaArrayCellData, DynamicFormulaArrayCellData # Handle formulas. # # We only try to autofit a formula if it has a # non-zero value. if ptrue?(cell_data.data) length = xl_string_pixel_width(cell_data.data) end end # If the cell is in an autofilter header we add an # additional 16 pixels for the dropdown arrow. if length > 0 && @filter_cells["#{row_num}:#{col_num}"] length += 16 end # Add the string lenght to the lookup hash. max = col_width[col_num] || 0 col_width[col_num] = length if length > max end end # Apply the width to the column. col_width.each do |col_num, pixel_width| # Convert the string pixel width to a character width using an # additional padding of 7 pixels, like Excel. width = pixels_to_width(pixel_width + 7) # Limit the width to the maximum user or Excel value. width = max_width if width > max_width # Add the width to an existing col info structure or add a new one. if @col_info[col_num] @col_info[col_num].width = width @col_info[col_num].autofit = 1 else @col_info[col_num] = COLINFO.new(width, nil, 0, 0, 0, 1) end end end |
#set_column(*args) ⇒ Object
:call-seq:
set_column(firstcol, lastcol, width, format, hidden, level, collapsed)
This method can be used to change the default properties of a single column or a range of columns. All parameters apart from first_col and last_col are optional.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/write_xlsx/worksheet/columns.rb', line 13 def set_column(*args) # Check for a cell reference in A1 notation and substitute row and column # ruby 3.2 no longer handles =~ for various types if args[0].respond_to?(:=~) && args[0].to_s =~ /^\D/ _row1, firstcol, _row2, lastcol, *data = substitute_cellref(*args) else firstcol, lastcol, *data = args end # Ensure at least firstcol, lastcol and width return unless firstcol && lastcol && !data.empty? # Assume second column is the same as first if 0. Avoids KB918419 bug. lastcol = firstcol unless ptrue?(lastcol) # Ensure 2nd col is larger than first. Also for KB918419 bug. firstcol, lastcol = lastcol, firstcol if firstcol > lastcol width, format, hidden, level, collapsed = data autofit = 0 # Check that cols are valid and store max and min values with default row. # NOTE: The check shouldn't modify the row dimensions and should only modify # the column dimensions in certain cases. ignore_row = 1 ignore_col = 1 ignore_col = 0 if format.respond_to?(:xf_index) # Column has a format. ignore_col = 0 if width && ptrue?(hidden) # Column has a width but is hidden check_dimensions_and_update_max_min_values(0, firstcol, ignore_row, ignore_col) check_dimensions_and_update_max_min_values(0, lastcol, ignore_row, ignore_col) # Set the limits for the outline levels (0 <= x <= 7). level ||= 0 level = 0 if level < 0 level = 7 if level > 7 # Excel has a maximum column width of 255 characters. width = 255.0 if width && width > 255.0 @outline_col_level = level if level > @outline_col_level # Store the column data based on the first column. Padded for sorting. (firstcol..lastcol).each do |col| @col_info[col] = COLINFO.new(width, format, hidden, level, collapsed, autofit) end # Store the column change to allow optimisations. @col_size_changed = true end |
#set_column_pixels(*data) ⇒ Object
Set the width (and properties) of a single column or a range of columns in pixels rather than character units.
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/write_xlsx/worksheet/columns.rb', line 69 def set_column_pixels(*data) cell = data[0] # Check for a cell reference in A1 notation and substitute row and column if cell =~ /^\D/ data = substitute_cellref(*data) # Returned values row1 and row2 aren't required here. Remove them. data.shift # $row1 data.delete_at(1) # $row2 end # Ensure at least $first_col, $last_col and $width return if data.size < 3 first_col, last_col, pixels, format, hidden, level = data hidden ||= 0 width = pixels_to_width(pixels) if ptrue?(pixels) set_column(first_col, last_col, width, format, hidden, level) end |