|
99 | 99 |
|
100 | 100 | if ((((ln * h) + y + (h * 2)) / pages) >= this.internal.pageSize.height && pages === 1 && !newPage) { |
101 | 101 | this.cellAddPage(); |
| 102 | + |
102 | 103 | if(this.printHeaders && this.tableHeaderRow){ |
103 | 104 | this.printHeaderRow(ln); |
104 | 105 | this.lnMod++; |
|
109 | 110 | } |
110 | 111 | } else if (newPage && getLastCellPosition().ln !== ln && getLnP() === getMaxLn()) { |
111 | 112 | this.cellAddPage(); |
| 113 | + |
112 | 114 | if(this.printHeaders && this.tableHeaderRow){ |
113 | 115 | this.printHeaderRow(ln); |
114 | 116 | this.lnMod++; |
|
144 | 146 | return this; |
145 | 147 | }; |
146 | 148 |
|
| 149 | + /** |
| 150 | + * Return an array containing all of the owned keys of an Object |
| 151 | + * @type {Function} |
| 152 | + * @return {String[]} of Object keys |
| 153 | + */ |
| 154 | + jsPDFAPI.getKeys = (typeof Object.keys == 'function') |
| 155 | + ? function(object){ |
| 156 | + if (!object) { |
| 157 | + return []; |
| 158 | + } |
| 159 | + return Object.keys(object); |
| 160 | + } |
| 161 | + : function(object) { |
| 162 | + var keys = [], |
| 163 | + property; |
| 164 | + |
| 165 | + for (property in object) { |
| 166 | + if (object.hasOwnProperty(property)) { |
| 167 | + keys.push(property); |
| 168 | + } |
| 169 | + } |
| 170 | + |
| 171 | + return keys; |
| 172 | + }; |
| 173 | + |
| 174 | + /** |
| 175 | + * Return the maximum value from an array |
| 176 | + * @param array |
| 177 | + * @param comparisonFn |
| 178 | + * @returns {*} |
| 179 | + */ |
| 180 | + jsPDFAPI.arrayMax = function(array, comparisonFn) { |
| 181 | + var max = array[0], |
| 182 | + i, ln, item; |
| 183 | + |
| 184 | + for (i = 0, ln = array.length; i < ln; i++) { |
| 185 | + item = array[i]; |
| 186 | + |
| 187 | + if (comparisonFn) { |
| 188 | + if (comparisonFn(max, item) === -1) { |
| 189 | + max = item; |
| 190 | + } |
| 191 | + } |
| 192 | + else { |
| 193 | + if (item > max) { |
| 194 | + max = item; |
| 195 | + } |
| 196 | + } |
| 197 | + } |
| 198 | + |
| 199 | + return max; |
| 200 | + }; |
147 | 201 |
|
148 | 202 | /** |
149 | | - * Create a table from an {#Ext.data.Store} or a set of data. |
150 | | - * @param {Ext.data.Model[]|Ext.data.Store} dataSet |
| 203 | + * Create a table from a set of data. |
| 204 | + * @param {Object[]} dataSet As array of objects containing key-value pairs |
151 | 205 | * @param {Array} [headers] Omit or null to auto-generate headers at a performance cost |
152 | | - * @param {Object} [config.printColumnHeaders] True to print column headers at the top of every page |
| 206 | + * @param {Object} [config.printHeaders] True to print column headers at the top of every page |
153 | 207 | * @param {Object} [config.autoSize] True to dynamically set the column widths to match the widest cell value |
154 | 208 | * @param {Object} [config.autoStretch] True to force the table to fit the width of the page |
155 | 209 | */ |
156 | 210 | jsPDFAPI.table = function(dataSet, headers, config){ |
157 | 211 |
|
158 | 212 | var models; |
159 | 213 |
|
| 214 | + /** |
| 215 | + * @property {Number} lnMod |
| 216 | + * Keep track of the current line number modifier used when creating cells |
| 217 | + */ |
160 | 218 | this.lnMod = 0; |
161 | 219 |
|
162 | 220 | if(config){ |
163 | 221 | var autoSize = config.autoSize || false, |
164 | | - printHeaders = this.printHeaders = config.printColumnHeaders || true, |
| 222 | + printHeaders = this.printHeaders = config.printHeaders || true, |
165 | 223 | autoStretch = config.autoStretch || true; |
166 | 224 | } |
167 | 225 |
|
|
179 | 237 | // Set headers |
180 | 238 | if(headers === undefined || (headers === null)){ |
181 | 239 | // No headers defined so we derive from data |
182 | | - if(isStore){ |
183 | | - headers = Ext.Array.pluck(dataSet.model.getFields(), 'name'); |
184 | | - } else { |
185 | | - headers = Ext.Object.getKeys(models[0]); |
186 | | - } |
187 | | -// console.log(headers); |
| 240 | + headers = this.getKeys(models[0]); |
188 | 241 | } |
189 | 242 |
|
190 | | - // Create Columns Matrix |
191 | | - var columnMatrix = {}, |
192 | | - columnWidths = {}, |
193 | | - index, |
194 | | - columnData; |
195 | | - |
196 | | - for (var i = 0, ln = headers.length; i < ln; i++) { |
197 | | - index = headers[i]; |
198 | | - columnMatrix[index] = Ext.Array.map(models, function(rec){ |
199 | | - if(!rec.get){ |
200 | | - console.log(rec.$className); |
201 | | - } |
202 | | - return rec.get(index); |
203 | | - }); |
| 243 | + if(config.autoSize){ |
204 | 244 |
|
205 | | - var columnMinWidths = [], column; |
| 245 | + // Create Columns Matrix |
| 246 | + var columnMatrix = {}, |
| 247 | + columnWidths = {}, |
| 248 | + index, |
| 249 | + columnData; |
206 | 250 |
|
207 | | - // get header width |
208 | | - columnMinWidths.push(this.getTextDimensions(index).w); |
209 | | -// columnMinWidths.push(TextMetrics.getWidth(index)/3.7795275593333); |
| 251 | + for (var i = 0, ln = headers.length; i < ln; i++) { |
| 252 | + index = headers[i]; |
| 253 | + columnMatrix[index] = models.map(function(rec){ |
| 254 | + return rec[index]; |
| 255 | + }); |
210 | 256 |
|
211 | | - column = columnMatrix[index]; |
| 257 | + var columnMinWidths = [], column; |
212 | 258 |
|
213 | | - // Get cell widths |
214 | | - for (var j = 0, ln = columnMatrix[index].length; j < ln; j++) { |
215 | | - columnData = columnMatrix[index][j]; |
216 | | - columnMinWidths.push(this.getTextDimensions(columnData).w); |
| 259 | + // get header width |
| 260 | + columnMinWidths.push(this.getTextDimensions(index).w); |
| 261 | + column = columnMatrix[index]; |
217 | 262 |
|
218 | | -// columnMinWidths.push(TextMetrics.getWidth(columnData)/3.7795275593333); |
219 | | - } |
| 263 | + // Get cell widths |
| 264 | + for (var j = 0, ln = columnMatrix[index].length; j < ln; j++) { |
| 265 | + columnData = columnMatrix[index][j]; |
| 266 | + columnMinWidths.push(this.getTextDimensions(columnData).w); |
| 267 | + } |
220 | 268 |
|
221 | | - // get final column width |
222 | | - columnWidths[index] = Ext.Array.max(columnMinWidths); |
| 269 | + // get final column width |
| 270 | + columnWidths[index] = jsPDFAPI.arrayMax(columnMinWidths); |
| 271 | + } |
223 | 272 | } |
224 | 273 |
|
225 | | - // Construct the table |
| 274 | + // -- Construct the table |
226 | 275 |
|
227 | | - // Construct the header row |
228 | | - var header, tableHeaderConfigs = []; |
229 | | - for (var i = 0, ln = headers.length; i < ln; i++) { |
230 | | - header = headers[i]; |
231 | | - tableHeaderConfigs.push([10, 10, columnWidths[header], 25, String(header)]); |
232 | | - } |
| 276 | + if (config.printHeaders){ |
233 | 277 |
|
234 | | - this.setTableHeaderRow(tableHeaderConfigs); |
| 278 | + // Construct the header row |
| 279 | + var header, tableHeaderConfigs = []; |
235 | 280 |
|
236 | | - this.printHeaderRow(1); |
| 281 | + for (var i = 0, ln = headers.length; i < ln; i++) { |
| 282 | + header = headers[i]; |
| 283 | + tableHeaderConfigs.push([10, 10, columnWidths[header], 25, String(header)]); |
| 284 | + } |
| 285 | + |
| 286 | + // Store the table header config |
| 287 | + this.setTableHeaderRow(tableHeaderConfigs); |
| 288 | + |
| 289 | + // Print the header for the start of the table |
| 290 | + this.printHeaderRow(1); |
| 291 | + } |
237 | 292 |
|
238 | 293 | // Construct the data rows |
239 | | - var record; |
| 294 | + var model; |
240 | 295 |
|
241 | 296 | for (var i = 0, ln = models.length; i < ln; i++) { |
242 | | - record = models[i]; |
| 297 | + model = models[i]; |
243 | 298 |
|
244 | 299 | for (var j = 0, jln = headers.length; j < jln; j++) { |
245 | 300 | index = headers[j]; |
246 | | - this.cell(10, 10, columnWidths[index], 25, String(record.get(index)), i+2); |
| 301 | + this.cell(10, 10, columnWidths[index], 25, String(model[index]), i+2); |
247 | 302 | } |
248 | 303 | } |
249 | 304 |
|
250 | 305 | return this; |
251 | 306 | }; |
252 | 307 |
|
| 308 | + /** |
| 309 | + * Store the config for outputting a table header |
| 310 | + * @param {Object[]} config |
| 311 | + * An array of cell configs that would define a header row: Each config matches the config used by jsPDFAPI.cell |
| 312 | + * except the ln parameter is excluded |
| 313 | + */ |
253 | 314 | jsPDFAPI.setTableHeaderRow = function(config){ |
254 | 315 | this.tableHeaderRow = config; |
255 | 316 | }; |
256 | 317 |
|
| 318 | + /** |
| 319 | + * Output the store header row |
| 320 | + * @param lineNumber The line number to output the header at |
| 321 | + */ |
257 | 322 | jsPDFAPI.printHeaderRow = function(lineNumber){ |
| 323 | + |
| 324 | + if (!this.tableHeaderRow){ |
| 325 | + throw 'Property tableHeaderRow does not exist.'; |
| 326 | + } |
| 327 | + |
| 328 | + var tableHeaderCell, tmpArray; |
| 329 | + |
258 | 330 | this.printingHeaderRow = true; |
| 331 | + |
259 | 332 | for (var i = 0, ln = this.tableHeaderRow.length; i < ln; i++) { |
260 | | - var tableHeaderCell = this.tableHeaderRow[i]; |
261 | | - var tmp = [].concat(tableHeaderCell); |
262 | | - tmp = tmp.concat(lineNumber); |
263 | | - this.cell.apply(this,tmp); |
| 333 | + |
| 334 | + tableHeaderCell = this.tableHeaderRow[i]; |
| 335 | + tmpArray = [].concat(tableHeaderCell); |
| 336 | + |
| 337 | + this.cell.apply(this, tmpArray.concat(lineNumber)); |
264 | 338 | } |
| 339 | + |
265 | 340 | this.printingHeaderRow = false; |
266 | 341 | }; |
267 | 342 |
|
|
0 commit comments