1 var _typeof = typeof Symbol ===
"function" && typeof Symbol.iterator ===
"symbol" ?
function (obj) {
return typeof obj; } :
function (obj) {
return obj && typeof Symbol ===
"function" && obj.constructor === Symbol && obj !== Symbol.prototype ?
"symbol" : typeof obj; };
5 var Download =
function Download(table) {
8 this.columnsByIndex = [];
9 this.columnsByField = {};
15 Download.prototype.download =
function (type, filename, options, active, interceptCallback) {
21 function buildLink(data, mime) {
22 if (interceptCallback) {
23 if (interceptCallback ===
true) {
24 self.triggerDownload(data, mime, type, filename,
true);
26 interceptCallback(data);
29 self.triggerDownload(data, mime, type, filename);
33 if (typeof type ==
"function") {
36 if (
self.downloaders[type]) {
37 downloadFunc =
self.downloaders[type];
39 console.warn(
"Download Error - No such download type found: ", type);
43 this.processColumns();
46 downloadFunc.call(
this,
self.processDefinitions(),
self.processData(active ||
"active"), options || {}, buildLink, this.config);
50 Download.prototype.processConfig =
function () {
57 if (this.table.options.downloadConfig) {
58 for (var key in this.table.options.downloadConfig) {
59 config[key] = this.table.options.downloadConfig[key];
63 if (config.rowGroups &&
this.table.options.groupBy &&
this.table.modExists(
"groupRows")) {
64 this.config.rowGroups =
true;
67 if (config.columnGroups &&
this.table.columnManager.columns.length !=
this.table.columnManager.columnsByIndex.length) {
68 this.config.columnGroups =
true;
71 if (config.columnCalcs &&
this.table.modExists(
"columnCalcs")) {
72 this.config.columnCalcs =
true;
76 Download.prototype.processColumns =
function () {
79 self.columnsByIndex = [];
80 self.columnsByField = {};
82 self.table.columnManager.columnsByIndex.forEach(
function (column) {
84 if (column.field && column.definition.download !==
false && (column.visible || !column.visible && column.definition.download)) {
85 self.columnsByIndex.push(column);
86 self.columnsByField[column.field] = column;
91 Download.prototype.processDefinitions =
function () {
93 processedDefinitions = [];
95 if (this.config.columnGroups) {
96 self.table.columnManager.columns.forEach(
function (column) {
97 var colData =
self.processColumnGroup(column);
100 processedDefinitions.push(colData);
104 self.columnsByIndex.forEach(
function (column) {
105 if (column.download !==
false) {
107 processedDefinitions.push(
self.processDefinition(column));
112 return processedDefinitions;
115 Download.prototype.processColumnGroup =
function (column) {
118 var subGroups = column.columns,
120 var processedColumn = this.processDefinition(column);
123 title: processedColumn.title,
127 if (subGroups.length) {
128 groupData.subGroups = [];
131 subGroups.forEach(
function (subGroup) {
132 var subGroupData = _this.processColumnGroup(subGroup);
134 if (subGroupData.depth > maxDepth) {
135 maxDepth = subGroupData.depth;
139 groupData.width += subGroupData.width;
140 groupData.subGroups.push(subGroupData);
144 groupData.depth += maxDepth;
146 if (!groupData.width) {
150 if (column.field && column.definition.download !==
false && (column.visible || !column.visible && column.definition.download)) {
152 groupData.definition = processedColumn;
161 Download.prototype.processDefinition =
function (column) {
164 for (var key in column.definition) {
165 def[key] = column.definition[key];
168 if (typeof column.definition.downloadTitle !=
"undefined") {
169 def.title = column.definition.downloadTitle;
175 Download.prototype.processData =
function (active) {
184 if (this.config.rowGroups) {
186 if (active ==
"visible") {
188 rows =
self.table.rowManager.getRows(active);
190 rows.forEach(
function (row) {
191 if (row.type ==
"row") {
192 var group = row.getGroup();
194 if (groups.indexOf(group) === -1) {
200 groups = this.table.modules.groupRows.getGroups();
203 groups.forEach(
function (group) {
204 data.push(_this2.processGroupData(group, rows));
207 data =
self.table.rowManager.getData(active,
"download");
210 if (this.config.columnCalcs) {
211 calcs = this.table.getCalcResults();
220 if (typeof
self.table.options.downloadDataFormatter ==
"function") {
221 data =
self.table.options.downloadDataFormatter(data);
227 Download.prototype.processGroupData =
function (group, visRows) {
230 var subGroups = group.getSubGroups();
237 if (subGroups.length) {
238 groupData.subGroups = [];
240 subGroups.forEach(
function (subGroup) {
241 groupData.subGroups.push(_this3.processGroupData(subGroup, visRows));
247 group.rows.forEach(
function (row) {
248 if (visRows.indexOf(row) > -1) {
249 groupData.rows.push(row.getData(
"download"));
253 groupData.rows = group.getData(
true,
"download");
260 Download.prototype.triggerDownload =
function (data, mime, type, filename, newTab) {
261 var element = document.createElement(
'a'),
262 blob =
new Blob([data], { type: mime }),
263 filename = filename ||
"Tabulator." + (typeof type ===
"function" ?
"txt" : type);
265 blob = this.table.options.downloadReady.call(this.table, data, blob);
270 window.open(window.URL.createObjectURL(blob));
272 if (navigator.msSaveOrOpenBlob) {
273 navigator.msSaveOrOpenBlob(blob, filename);
275 element.setAttribute(
'href', window.URL.createObjectURL(blob));
278 element.setAttribute(
'download', filename);
281 element.style.display =
'none';
282 document.body.appendChild(element);
286 document.body.removeChild(element);
290 if (this.table.options.downloadComplete) {
291 this.table.options.downloadComplete();
297 Download.prototype.getFieldValue =
function (field, data) {
298 var column = this.columnsByField[field];
301 return column.getFieldValue(data);
307 Download.prototype.commsReceived =
function (table, action, data) {
310 this.download(data.type,
"", data.options, data.active, data.intercept);
316 Download.prototype.downloaders = {
317 csv:
function csv(columns, data, options, setFileContents, config) {
321 delimiter = options && options.delimiter ? options.delimiter :
",",
326 function parseSimpleTitles() {
327 columns.forEach(
function (column) {
328 titles.push(
'"' + String(column.title).split(
'"').join(
'""') +
'"');
329 fields.push(column.field);
333 function parseColumnGroup(column, level) {
334 if (column.subGroups) {
335 column.subGroups.forEach(
function (subGroup) {
336 parseColumnGroup(subGroup, level + 1);
339 titles.push(
'"' + String(column.title).split(
'"').join(
'""') +
'"');
340 fields.push(column.definition.field);
344 if (config.columnGroups) {
345 console.warn(
"Download Warning - CSV downloader cannot process column groups");
347 columns.forEach(
function (column) {
348 parseColumnGroup(column, 0);
355 fileContents = [titles.join(delimiter)];
357 function parseRows(data) {
359 data.forEach(
function (row) {
362 fields.forEach(
function (field) {
363 var value =
self.getFieldValue(field, row);
365 switch (typeof value ===
"undefined" ?
"undefined" : _typeof(value)) {
367 value = JSON.stringify(value);
380 rowData.push(
'"' + String(value).split(
'"').join(
'""') +
'"');
383 fileContents.push(rowData.join(delimiter));
387 function parseGroup(group) {
388 if (group.subGroups) {
389 group.subGroups.forEach(
function (subGroup) {
390 parseGroup(subGroup);
393 parseRows(group.rows);
397 if (config.columnCalcs) {
398 console.warn(
"Download Warning - CSV downloader cannot process column calculations");
402 if (config.rowGroups) {
403 console.warn(
"Download Warning - CSV downloader cannot process row groups");
405 data.forEach(
function (group) {
412 output = fileContents.join(
"\n");
415 output =
"\uFEFF" + output;
418 setFileContents(output,
"text/csv");
421 json:
function json(columns, data, options, setFileContents, config) {
424 if (config.columnCalcs) {
425 console.warn(
"Download Warning - CSV downloader cannot process column calculations");
429 fileContents = JSON.stringify(data, null,
'\t');
431 setFileContents(fileContents,
"application/json");
434 pdf:
function pdf(columns, data, options, setFileContents, config) {
442 autoTableParams = {},
443 rowGroupStyles = options.rowGroupStyles || {
449 rowCalcStyles = options.rowCalcStyles || {
455 jsPDFParams = options.jsPDF || {},
456 title = options && options.title ? options.title :
"";
458 if (config.columnCalcs) {
463 if (!jsPDFParams.orientation) {
464 jsPDFParams.orientation = options.orientation ||
"landscape";
467 if (!jsPDFParams.unit) {
468 jsPDFParams.unit =
"pt";
472 function parseSimpleTitles() {
473 columns.forEach(
function (column) {
475 header.push(column.title ||
"");
476 fields.push(column.field);
483 function parseColumnGroup(column, level) {
484 var colSpan = column.width,
487 content: column.title ||
""
490 if (column.subGroups) {
491 column.subGroups.forEach(
function (subGroup) {
492 parseColumnGroup(subGroup, level + 1);
496 fields.push(column.definition.field);
497 rowSpan = headerDepth - level;
500 col.rowSpan = rowSpan;
503 header[level].push(col);
508 for (var i = level + 1; i < headerDepth; i++) {
513 for (var i = 0; i < colSpan; i++) {
514 header[level].push(
"");
518 if (config.columnGroups) {
519 columns.forEach(
function (column) {
520 if (column.depth > headerDepth) {
521 headerDepth = column.depth;
525 for (var i = 0; i < headerDepth; i++) {
529 columns.forEach(
function (column) {
530 parseColumnGroup(column, 0);
536 function parseValue(value) {
537 switch (typeof value ===
"undefined" ?
"undefined" : _typeof(value)) {
539 value = JSON.stringify(value);
554 function parseRows(data) {
556 data.forEach(
function (row) {
557 body.push(parseRow(row));
561 function parseRow(row, styles) {
564 fields.forEach(
function (field) {
565 var value =
self.getFieldValue(field, row);
566 value = parseValue(value);
581 function parseGroup(group, calcObj) {
584 groupData.push({ content: parseValue(group.key), colSpan: fields.length, styles: rowGroupStyles });
586 body.push(groupData);
588 if (group.subGroups) {
589 group.subGroups.forEach(
function (subGroup) {
590 parseGroup(subGroup, calcObj[group.key] ? calcObj[group.key].groups || {} : {});
594 if (config.columnCalcs) {
595 addCalcRow(calcObj, group.key,
"top");
598 parseRows(group.rows);
600 if (config.columnCalcs) {
601 addCalcRow(calcObj, group.key,
"bottom");
606 function addCalcRow(calcs, selector, pos) {
607 var calcData = calcs[selector];
611 calcData = calcData[pos];
614 if (Object.keys(calcData).length) {
615 body.push(parseRow(calcData, rowCalcStyles));
620 if (config.rowGroups) {
621 data.forEach(
function (group) {
622 parseGroup(group, calcs);
625 if (config.columnCalcs) {
626 addCalcRow(calcs,
"top");
631 if (config.columnCalcs) {
632 addCalcRow(calcs,
"bottom");
636 var doc =
new jsPDF(jsPDFParams);
638 if (options && options.autoTable) {
639 if (typeof options.autoTable ===
"function") {
640 autoTableParams = options.autoTable(doc) || {};
642 autoTableParams = options.autoTable;
647 autoTableParams.addPageContent =
function (data) {
648 doc.text(title, 40, 30);
652 autoTableParams.head = header;
653 autoTableParams.body = body;
655 doc.autoTable(autoTableParams);
657 if (options && options.documentProcessing) {
658 options.documentProcessing(doc);
661 setFileContents(doc.output(
"arraybuffer"),
"application/pdf");
664 xlsx:
function xlsx(columns, data, options, setFileContents, config) {
666 sheetName = options.sheetName ||
"Sheet1",
667 workbook = XLSX.utils.book_new(),
670 groupColumnIndexs = [],
674 workbook.SheetNames = [];
675 workbook.Sheets = {};
677 if (config.columnCalcs) {
682 function generateSheet() {
689 function rowsToSheet() {
691 var range = { s: { c: 0, r: 0 }, e: { c: fields.length, r: rows.length } };
693 XLSX.utils.sheet_add_aoa(sheet, rows);
695 sheet[
'!ref'] = XLSX.utils.encode_range(range);
697 var merges = generateMerges();
700 sheet[
"!merges"] = merges;
706 function parseSimpleTitles() {
708 columns.forEach(
function (column) {
709 titles.push(column.title);
710 fields.push(column.field);
716 function parseColumnGroup(column, level) {
718 if (typeof titles[level] ===
"undefined") {
722 if (typeof groupColumnIndexs[level] ===
"undefined") {
723 groupColumnIndexs[level] = [];
726 if (column.width > 1) {
728 groupColumnIndexs[level].push({
730 start: titles[level].length,
731 end: titles[level].length + column.width - 1
735 titles[level].push(column.title);
737 if (column.subGroups) {
738 column.subGroups.forEach(
function (subGroup) {
739 parseColumnGroup(subGroup, level + 1);
742 fields.push(column.definition.field);
743 padColumnTitles(fields.length - 1, level);
745 groupColumnIndexs[level].push({
747 start: fields.length - 1
752 function padColumnTitles() {
755 titles.forEach(
function (title) {
756 var len = title.length;
762 titles.forEach(
function (title) {
763 var len = title.length;
765 for (var i = len; i < max; i++) {
772 if (config.columnGroups) {
773 columns.forEach(
function (column) {
774 parseColumnGroup(column, 0);
777 titles.forEach(
function (title) {
784 function generateMerges() {
787 groupRowIndexs.forEach(
function (index) {
788 output.push({ s: { r: index, c: 0 }, e: { r: index, c: fields.length - 1 } });
791 groupColumnIndexs.forEach(
function (merges, level) {
792 merges.forEach(
function (merge) {
793 if (merge.type ===
"hoz") {
794 output.push({ s: { r: level, c: merge.start }, e: { r: level, c: merge.end } });
796 if (level != titles.length - 1) {
797 output.push({ s: { r: level, c: merge.start }, e: { r: titles.length - 1, c: merge.start } });
807 function parseRows(data) {
808 data.forEach(
function (row) {
809 rows.push(parseRow(row));
813 function parseRow(row) {
816 fields.forEach(
function (field) {
817 var value =
self.getFieldValue(field, row);
818 rowData.push(!(value instanceof Date) && (typeof value ===
"undefined" ?
"undefined" : _typeof(value)) ===
"object" ? JSON.stringify(value) : value);
824 function addCalcRow(calcs, selector, pos) {
825 var calcData = calcs[selector];
829 calcData = calcData[pos];
832 if (Object.keys(calcData).length) {
833 calcRowIndexs.push(rows.length);
834 rows.push(parseRow(calcData));
839 function parseGroup(group, calcObj) {
842 groupData.push(group.key);
844 groupRowIndexs.push(rows.length);
846 rows.push(groupData);
848 if (group.subGroups) {
849 group.subGroups.forEach(
function (subGroup) {
850 parseGroup(subGroup, calcObj[group.key] ? calcObj[group.key].groups || {} : {});
854 if (config.columnCalcs) {
855 addCalcRow(calcObj, group.key,
"top");
858 parseRows(group.rows);
860 if (config.columnCalcs) {
861 addCalcRow(calcObj, group.key,
"bottom");
866 if (config.rowGroups) {
867 data.forEach(
function (group) {
868 parseGroup(group, calcs);
871 if (config.columnCalcs) {
872 addCalcRow(calcs,
"top");
877 if (config.columnCalcs) {
878 addCalcRow(calcs,
"bottom");
882 worksheet = rowsToSheet();
887 if (options.sheetOnly) {
888 setFileContents(generateSheet());
892 if (options.sheets) {
893 for (var sheet in options.sheets) {
895 if (options.sheets[sheet] ===
true) {
896 workbook.SheetNames.push(sheet);
897 workbook.Sheets[sheet] = generateSheet();
900 workbook.SheetNames.push(sheet);
902 this.table.modules.comms.send(options.sheets[sheet],
"download",
"intercept", {
904 options: { sheetOnly:
true },
906 intercept:
function intercept(data) {
907 workbook.Sheets[sheet] = data;
913 workbook.SheetNames.push(sheetName);
914 workbook.Sheets[sheetName] = generateSheet();
917 if (options.documentProcessing) {
918 workbook = options.documentProcessing(workbook);
923 var buf =
new ArrayBuffer(s.length);
924 var view =
new Uint8Array(buf);
925 for (var i = 0; i != s.length; ++i) {
926 view[i] = s.charCodeAt(i) & 0xFF;
930 output = XLSX.write(workbook, { bookType:
'xlsx', bookSST:
true, type:
'binary' });
932 setFileContents(s2ab(output),
"application/octet-stream");
935 html:
function html(columns, data, options, setFileContents, config) {
936 if (this.table.modExists(
"htmlTableExport",
true)) {
937 setFileContents(this.table.modules.htmlTableExport.getHtml(
true, options.style, config),
"text/html");
943 Tabulator.prototype.registerModule(
"download", Download);