修复报表多次点击搜索或换标签后可能卡死的问题;增加报表导出功能;

This commit is contained in:
chenjinsong
2018-07-12 19:14:26 +08:00
parent 207ac10d66
commit 65eba098e2
7 changed files with 934 additions and 8 deletions

View File

@@ -0,0 +1,253 @@
/* FileSaver.js
* A saveAs() FileSaver implementation.
* 2015-05-07.2
*
* By Eli Grey, http://eligrey.com
* License: X11/MIT
* See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md
*/
/*global self */
/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */
/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
var saveAs = saveAs || (function(view) {
"use strict";
// IE <10 is explicitly unsupported
if (typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) {
return;
}
var
doc = view.document
// only get URL when necessary in case Blob.js hasn't overridden it yet
, get_URL = function() {
return view.URL || view.webkitURL || view;
}
, save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a")
, can_use_save_link = "download" in save_link
, click = function(node) {
var event = doc.createEvent("MouseEvents");
event.initMouseEvent(
"click", true, false, view, 0, 0, 0, 0, 0
, false, false, false, false, 0, null
);
node.dispatchEvent(event);
}
, webkit_req_fs = view.webkitRequestFileSystem
, req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem
, throw_outside = function(ex) {
(view.setImmediate || view.setTimeout)(function() {
throw ex;
}, 0);
}
, force_saveable_type = "application/octet-stream"
, fs_min_size = 0
// See https://code.google.com/p/chromium/issues/detail?id=375297#c7 and
// https://github.com/eligrey/FileSaver.js/commit/485930a#commitcomment-8768047
// for the reasoning behind the timeout and revocation flow
, arbitrary_revoke_timeout = 500 // in ms
, revoke = function(file) {
var revoker = function() {
if (typeof file === "string") { // file is an object URL
get_URL().revokeObjectURL(file);
} else { // file is a File
file.remove();
}
};
if (view.chrome) {
revoker();
} else {
setTimeout(revoker, arbitrary_revoke_timeout);
}
}
, dispatch = function(filesaver, event_types, event) {
event_types = [].concat(event_types);
var i = event_types.length;
while (i--) {
var listener = filesaver["on" + event_types[i]];
if (typeof listener === "function") {
try {
listener.call(filesaver, event || filesaver);
} catch (ex) {
throw_outside(ex);
}
}
}
}
, auto_bom = function(blob) {
// prepend BOM for UTF-8 XML and text/* types (including HTML)
if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
return new Blob(["\ufeff", blob], {type: blob.type});
}
return blob;
}
, FileSaver = function(blob, name) {
blob = auto_bom(blob);
// First try a.download, then web filesystem, then object URLs
var
filesaver = this
, type = blob.type
, blob_changed = false
, object_url
, target_view
, dispatch_all = function() {
dispatch(filesaver, "writestart progress write writeend".split(" "));
}
// on any filesys errors revert to saving with object URLs
, fs_error = function() {
// don't create more object URLs than needed
if (blob_changed || !object_url) {
object_url = get_URL().createObjectURL(blob);
}
if (target_view) {
target_view.location.href = object_url;
} else {
var new_tab = view.open(object_url, "_blank");
if (new_tab == undefined && typeof safari !== "undefined") {
//Apple do not allow window.open, see http://bit.ly/1kZffRI
view.location.href = object_url
}
}
filesaver.readyState = filesaver.DONE;
dispatch_all();
revoke(object_url);
}
, abortable = function(func) {
return function() {
if (filesaver.readyState !== filesaver.DONE) {
return func.apply(this, arguments);
}
};
}
, create_if_not_found = {create: true, exclusive: false}
, slice
;
filesaver.readyState = filesaver.INIT;
if (!name) {
name = "download";
}
if (can_use_save_link) {
object_url = get_URL().createObjectURL(blob);
save_link.href = object_url;
save_link.download = name;
click(save_link);
filesaver.readyState = filesaver.DONE;
dispatch_all();
revoke(object_url);
return;
}
// Object and web filesystem URLs have a problem saving in Google Chrome when
// viewed in a tab, so I force save with application/octet-stream
// http://code.google.com/p/chromium/issues/detail?id=91158
// Update: Google errantly closed 91158, I submitted it again:
// https://code.google.com/p/chromium/issues/detail?id=389642
if (view.chrome && type && type !== force_saveable_type) {
slice = blob.slice || blob.webkitSlice;
blob = slice.call(blob, 0, blob.size, force_saveable_type);
blob_changed = true;
}
// Since I can't be sure that the guessed media type will trigger a download
// in WebKit, I append .download to the filename.
// https://bugs.webkit.org/show_bug.cgi?id=65440
if (webkit_req_fs && name !== "download") {
name += ".download";
}
if (type === force_saveable_type || webkit_req_fs) {
target_view = view;
}
if (!req_fs) {
fs_error();
return;
}
fs_min_size += blob.size;
req_fs(view.TEMPORARY, fs_min_size, abortable(function(fs) {
fs.root.getDirectory("saved", create_if_not_found, abortable(function(dir) {
var save = function() {
dir.getFile(name, create_if_not_found, abortable(function(file) {
file.createWriter(abortable(function(writer) {
writer.onwriteend = function(event) {
target_view.location.href = file.toURL();
filesaver.readyState = filesaver.DONE;
dispatch(filesaver, "writeend", event);
revoke(file);
};
writer.onerror = function() {
var error = writer.error;
if (error.code !== error.ABORT_ERR) {
fs_error();
}
};
"writestart progress write abort".split(" ").forEach(function(event) {
writer["on" + event] = filesaver["on" + event];
});
writer.write(blob);
filesaver.abort = function() {
writer.abort();
filesaver.readyState = filesaver.DONE;
};
filesaver.readyState = filesaver.WRITING;
}), fs_error);
}), fs_error);
};
dir.getFile(name, {create: false}, abortable(function(file) {
// delete file if it already exists
file.remove();
save();
}), abortable(function(ex) {
if (ex.code === ex.NOT_FOUND_ERR) {
save();
} else {
fs_error();
}
}));
}), fs_error);
}), fs_error);
}
, FS_proto = FileSaver.prototype
, saveAs = function(blob, name) {
return new FileSaver(blob, name);
}
;
// IE 10+ (native saveAs)
if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) {
return function(blob, name) {
return navigator.msSaveOrOpenBlob(auto_bom(blob), name);
};
}
FS_proto.abort = function() {
var filesaver = this;
filesaver.readyState = filesaver.DONE;
dispatch(filesaver, "abort");
};
FS_proto.readyState = FS_proto.INIT = 0;
FS_proto.WRITING = 1;
FS_proto.DONE = 2;
FS_proto.error =
FS_proto.onwritestart =
FS_proto.onprogress =
FS_proto.onwrite =
FS_proto.onabort =
FS_proto.onerror =
FS_proto.onwriteend =
null;
return saveAs;
}(
typeof self !== "undefined" && self
|| typeof window !== "undefined" && window
|| this.content
));
// `self` is undefined in Firefox for Android content script context
// while `this` is nsIContentFrameMessageManager
// with an attribute `content` that corresponds to the window
if (typeof module !== "undefined" && module.exports) {
module.exports.saveAs = saveAs;
} else if ((typeof define !== "undefined" && define !== null) && (define.amd != null)) {
define([], function() {
return saveAs;
});
}

View File

@@ -0,0 +1,631 @@
/*!
* TableExport.js v3.3.13 (https://www.travismclarke.com)
*
* Copyright (c) 2017 - Travis Clarke - https://www.travismclarke.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
;(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['exports', 'jquery', 'blobjs', 'file-saverjs', 'xlsx-js'], factory);
} else if (typeof exports === 'object' && typeof exports.nodeName !== 'string') {
// CommonJS
factory(exports, require('jquery'), require('blobjs'), require('file-saverjs'), require('xlsx-js'));
} else {
// Browser globals
factory(root, root.jQuery, root.Blob, root.saveAs, root.XLSX);
}
}(this || window, function (exports, $, Blob, saveAs, XLSX) {
'use strict';
/**
* TableExport main plugin constructor
* @param selectors {jQuery} jQuery selector(s)
* @param options {Object} TableExport configuration options
* @param isUpdate {Boolean}
* @constructor
*/
var TableExport = function (selectors, options, isUpdate) {
var self = this;
/**
* TableExport configuration options (user-defined w/ default fallback)
*/
self.settings = isUpdate ? options : $.extend({}, TableExport.prototype.defaults, options);
/**
* jQuery selectors (tables) to apply the plugin to
*/
self.selectors = selectors;
var rowD = TableExport.prototype.rowDel,
isTrimWhitespace = self.settings.trimWhitespace,
ignoreRows = self.settings.ignoreRows instanceof Array ? self.settings.ignoreRows : [self.settings.ignoreRows],
ignoreCols = self.settings.ignoreCols instanceof Array ? self.settings.ignoreCols : [self.settings.ignoreCols],
ignoreCSS = self.settings.ignoreCSS instanceof Array ? self.settings.ignoreCSS.join(", ") : self.settings.ignoreCSS,
emptyCSS = self.settings.emptyCSS instanceof Array ? self.settings.emptyCSS.join(", ") : self.settings.emptyCSS,
bootstrapClass, bootstrapTheme, bootstrapSpacing;
if (self.settings.bootstrap) {
bootstrapClass = TableExport.prototype.bootstrap[0] + " ";
bootstrapTheme = TableExport.prototype.bootstrap[1] + " ";
bootstrapSpacing = TableExport.prototype.bootstrap[2] + " ";
} else {
bootstrapClass = TableExport.prototype.defaultButton + " ";
bootstrapTheme = bootstrapSpacing = "";
}
self.selectors.each(function () {
var $el = $(this);
if (isUpdate) {
$el.find('caption:not(.head)').remove();
}
var $rows = $el.find('tbody').find('tr'),
$rows = self.settings.headings ? $rows.add($el.find('thead>tr')) : $rows,
$rows = self.settings.footers ? $rows.add($el.find('tfoot>tr')) : $rows,
thAdj = self.settings.headings ? $el.find('thead>tr').length : 0,
fileName = self.settings.fileName === "id" ? ($el.attr('id') ? $el.attr('id') : TableExport.prototype.defaultFileName) : self.settings.fileName,
exporters = {
xlsx: function (rDel, name) {
var rcMap = {},
dataURL = $rows.map(function (ir, val) {
if (!!~ignoreRows.indexOf(ir - thAdj) || $(val).is(ignoreCSS)) {
return;
}
var $cols = $(val).find('th, td');
return [$cols.map(function (ic, val) {
if (!!~ignoreCols.indexOf(ic) || $(val).is(ignoreCSS)) {
return;
}
if ($(val).is(emptyCSS)) {
return " "
}
if (val.hasAttribute('colspan')) {
rcMap[ir] = rcMap[ir] || {};
rcMap[ir][ic + 1] = val.getAttribute('colspan') - 1
}
if (val.hasAttribute('rowspan')) {
for (var i = 1; i < val.getAttribute('rowspan'); i++) {
rcMap[ir + i] = rcMap[ir + i] || {};
rcMap[ir + i][ic] = 1
}
}
if (rcMap[ir]) {
var threshold = ic + 1,
total = 0,
count = 0;
for (var i = 0; i <= Math.max.apply(Math, Object.keys(rcMap[ir])); i++) {
(!rcMap[ir][i]) ? count++ : total = count >= ic ? total + rcMap[ir][i] : total;
if (count === threshold) {
break;
}
}
return new Array(total).concat({
v: TableExport.prototype.formatValue(isTrimWhitespace, $(val).text()),
t: TableExport.prototype.getType($(val).attr('class'))
});
}
return {
v: TableExport.prototype.formatValue(isTrimWhitespace, $(val).text()),
t: TableExport.prototype.getType($(val).attr('class'))
};
}).get()];
}).get(),
dataObject = TableExport.prototype.escapeHtml(
JSON.stringify({
data: dataURL,
fileName: name,
mimeType: TableExport.prototype.xlsx.mimeType,
fileExtension: TableExport.prototype.xlsx.fileExtension
})),
myContent = TableExport.prototype.xlsx.buttonContent,
myClass = TableExport.prototype.xlsx.defaultClass;
createObjButton(dataObject, myContent, myClass);
},
xlsm: function (rDel, name) {
var rcMap = {},
dataURL = $rows.map(function (ir, val) {
if (!!~ignoreRows.indexOf(ir - thAdj) || $(val).is(ignoreCSS)) {
return;
}
var $cols = $(val).find('th, td');
return [$cols.map(function (ic, val) {
if (!!~ignoreCols.indexOf(ic) || $(val).is(ignoreCSS)) {
return;
}
if ($(val).is(emptyCSS)) {
return " "
}
if (val.hasAttribute('colspan')) {
rcMap[ir] = rcMap[ir] || {};
rcMap[ir][ic + 1] = val.getAttribute('colspan') - 1
}
if (val.hasAttribute('rowspan')) {
for (var i = 1; i < val.getAttribute('rowspan'); i++) {
rcMap[ir + i] = rcMap[ir + i] || {};
rcMap[ir + i][ic] = 1
}
}
if (rcMap[ir]) {
var threshold = ic + 1,
total = 0,
count = 0;
for (var i = 0; i <= Math.max.apply(Math, Object.keys(rcMap[ir])); i++) {
(!rcMap[ir][i]) ? count++ : total = count >= ic ? total + rcMap[ir][i] : total;
if (count === threshold) {
break;
}
}
return new Array(total).concat({
v: TableExport.prototype.formatValue(isTrimWhitespace, $(val).text()),
t: TableExport.prototype.getType($(val).attr('class'))
});
}
return {
v: TableExport.prototype.formatValue(isTrimWhitespace, $(val).text()),
t: TableExport.prototype.getType($(val).attr('class'))
};
}).get()];
}).get(),
dataObject = TableExport.prototype.escapeHtml(
JSON.stringify({
data: dataURL,
fileName: name,
mimeType: TableExport.prototype.xls.mimeType,
fileExtension: TableExport.prototype.xls.fileExtension
})),
myContent = TableExport.prototype.xls.buttonContent,
myClass = TableExport.prototype.xls.defaultClass;
createObjButton(dataObject, myContent, myClass);
},
xls: function (rdel, name) {
var colD = TableExport.prototype.xls.separator,
dataURL = $rows.map(function (i, val) {
if (!!~ignoreRows.indexOf(i - thAdj) || $(val).is(ignoreCSS)) {
return;
}
var $cols = $(val).find('th, td');
return $cols.map(function (i, val) {
if (!!~ignoreCols.indexOf(i) || $(val).is(ignoreCSS)) {
return;
}
if ($(val).is(emptyCSS)) {
return " "
}
return {
v: TableExport.prototype.formatValue(isTrimWhitespace, $(val).text()),
t: TableExport.prototype.getType($(val).attr('class'))
};
}).get().join(colD);
}).get().join(rdel),
dataObject = TableExport.prototype.escapeHtml(
JSON.stringify({
data: dataURL,
fileName: name,
mimeType: TableExport.prototype.xls.mimeType,
fileExtension: TableExport.prototype.xls.fileExtension
})),
myContent = TableExport.prototype.xls.buttonContent,
myClass = TableExport.prototype.xls.defaultClass;
createObjButton(dataObject, myContent, myClass);
},
csv: function (rdel, name) {
var colD = TableExport.prototype.csv.separator,
dataURL = $rows.map(function (i, val) {
if (!!~ignoreRows.indexOf(i - thAdj) || $(val).is(ignoreCSS)) {
return;
}
var $cols = $(val).find('th, td');
return $cols.map(function (i, val) {
if (!!~ignoreCols.indexOf(i) || $(val).is(ignoreCSS)) {
return;
}
if ($(val).is(emptyCSS)) {
return " "
}
return '"' + TableExport.prototype.formatValue(isTrimWhitespace, $(val).text().replace(/"/g, '""')) + '"';
}).get().join(colD);
}).get().join(rdel),
dataObject = TableExport.prototype.escapeHtml(
JSON.stringify({
data: dataURL,
fileName: name,
mimeType: TableExport.prototype.csv.mimeType,
fileExtension: TableExport.prototype.csv.fileExtension
})),
myContent = TableExport.prototype.csv.buttonContent,
myClass = TableExport.prototype.csv.defaultClass;
createObjButton(dataObject, myContent, myClass);
},
txt: function (rdel, name) {
var colD = TableExport.prototype.txt.separator,
dataURL = $rows.map(function (i, val) {
if (!!~ignoreRows.indexOf(i - thAdj) || $(val).is(ignoreCSS)) {
return;
}
var $cols = $(val).find('th, td');
return $cols.map(function (i, val) {
if (!!~ignoreCols.indexOf(i) || $(val).is(ignoreCSS)) {
return;
}
if ($(val).is(emptyCSS)) {
return " "
}
return TableExport.prototype.formatValue(isTrimWhitespace, $(val).text());
}).get().join(colD);
}).get().join(rdel),
dataObject = TableExport.prototype.escapeHtml(
JSON.stringify({
data: dataURL,
fileName: name,
mimeType: TableExport.prototype.txt.mimeType,
fileExtension: TableExport.prototype.txt.fileExtension
})),
myContent = TableExport.prototype.txt.buttonContent,
myClass = TableExport.prototype.txt.defaultClass;
createObjButton(dataObject, myContent, myClass);
}
};
self.settings.formats.forEach(
function (key) {
XLSX && key === 'xls' ? key = 'xlsm' : false;
!XLSX && key === 'xlsx' ? key = null : false;
key && exporters[key](rowD, fileName);
}
);
/**
* Initializes table caption with export buttons
* @param exportButton {HTMLButtonElement}
*/
function checkCaption(exportButton) {
var $caption = $el.find('caption:not(.head)');
$caption.length ? $caption.append(exportButton) : $el.prepend('<caption style="display:none" class="' + bootstrapSpacing + self.settings.position + '">' + exportButton + '</caption>');
}
/**
* Creates file export buttons
* @param dataObject {JSON}
* @param myContent {String}
* @param myClass {String}
*/
function createObjButton(dataObject, myContent, myClass) {
var exportButton = "<button id='myexport' data-fileblob='" + dataObject + "' class='" + bootstrapClass + bootstrapTheme + myClass + "'>" + myContent + "</button>";
checkCaption(exportButton);
}
});
$("button[data-fileblob]")
.off("click")
.on("click", function () {
var object = $(this).data("fileblob"),
data = object.data,
fileName = object.fileName,
mimeType = object.mimeType,
fileExtension = object.fileExtension;
TableExport.prototype.export2file(data, mimeType, fileName, fileExtension);
});
return self;
};
TableExport.prototype = {
/**
* Version.
* @memberof TableExport.prototype
*/
version: "3.3.13",
/**
* Default plugin options.
* @memberof TableExport.prototype
*/
defaults: {
headings: true, // (Boolean), display table headings (th or td elements) in the <thead>, (default: true)
footers: true, // (Boolean), display table footers (th or td elements) in the <tfoot>, (default: false)
formats: ["xls", "csv", "txt"], // (String[]), filetype(s) for the export, (default: ["xls", "csv", "txt"])
fileName: "id", // (id, String), filename for the downloaded file, (default: "id")
bootstrap: true, // (Boolean), style buttons using bootstrap, (default: true)
position: "bottom", // (top, bottom), position of the caption element relative to table, (default: "bottom")
ignoreRows: null, // (Number, Number[]), row indices to exclude from the exported file(s) (default: null)
ignoreCols: null, // (Number, Number[]), column indices to exclude from the exported file(s) (default: null)
ignoreCSS: ".tableexport-ignore", // (selector, selector[]), selector(s) to exclude cells from the exported file(s) (default: ".tableexport-ignore")
emptyCSS: ".tableexport-empty", // (selector, selector[]), selector(s) to replace cells with an empty string in the exported file(s) (default: ".tableexport-empty")
trimWhitespace: false // (Boolean), remove all leading/trailing newlines, spaces, and tabs from cell text in the exported file(s) (default: false)
},
/**
* Character set (character encoding) of the HTML.
* @memberof TableExport.prototype
*/
charset: "charset=utf-8",
/**
* Filename fallback for exported files.
* @memberof TableExport.prototype
*/
defaultFileName: "myDownload",
/**
* Class applied to each export button element.
* @memberof TableExport.prototype
*/
defaultButton: "button-default",
/**
* Bootstrap configuration classes ["base", "theme", "container"].
* @memberof TableExport.prototype
*/
bootstrap: ["btn", "btn-default", "btn-toolbar"],
/**
* Row delimeter
* @memberof TableExport.prototype
*/
rowDel: "\r\n",
/**
* HTML entity mapping for special characters.
* @memberof TableExport.prototype
*/
entityMap: {"&": "&#38;", "<": "&#60;", ">": "&#62;", "'": '&#39;', "/": '&#47;'},
/**
* XLSX (Open XML spreadsheet) file extension configuration
* @memberof TableExport.prototype
*/
xlsx: {
defaultClass: "xlsx",
buttonContent: "Export to xlsx",
mimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
fileExtension: ".xlsx"
},
/**
* XLS (Binary spreadsheet) file extension configuration
* @memberof TableExport.prototype
*/
xls: {
defaultClass: "xls",
buttonContent: "Export to xls",
separator: "\t",
mimeType: "application/vnd.ms-excel",
fileExtension: ".xls"
},
/**
* CSV (Comma Separated Values) file extension configuration
* @memberof TableExport.prototype
*/
csv: {
defaultClass: "csv",
buttonContent: "Export to csv",
separator: ",",
mimeType: "text/csv",
fileExtension: ".csv"
},
/**
* TXT (Plain Text) file extension configuration
* @memberof TableExport.prototype
*/
txt: {
defaultClass: "txt",
buttonContent: "Export to txt",
separator: " ",
mimeType: "text/plain",
fileExtension: ".txt"
},
/**
* Cell-types override and assertion configuration
* @memberof TableExport.prototype
*/
types: {
string: {
defaultClass: "tableexport-string"
},
number: {
defaultClass: "tableexport-number",
assert: function (v) {
return !isNaN(v.replace(/,/g, ''));
}
},
boolean: {
defaultClass: "tableexport-boolean",
assert: function (v) {
return v.toLowerCase() === 'true' || v.toLowerCase() === 'false';
}
},
date: {
defaultClass: "tableexport-date",
assert: function (v) {
return !isNaN(Date.parse(v))
}
}
},
/**
* Escapes special characters with HTML entities
* @memberof TableExport.prototype
* @param string {String}
* @returns {String} escaped string
*/
escapeHtml: function (string) {
return String(string).replace(/[&<>'\/]/g, function (s) {
return TableExport.prototype.entityMap[s];
});
},
/**
* Removes leading/trailing whitespace from cell string
* @param isTrimWhitespace {Boolean}
* @param string {String}
* @returns {String} trimmed string
*/
formatValue: function (isTrimWhitespace, string) {
return isTrimWhitespace ? string.trim() : string;
},
/**
* Get cell data-type
* @param string {String}
* @returns {String} data-type
*/
getType: function (string) {
if (!string) return '';
var types = TableExport.prototype.types;
if (~string.indexOf(types.string.defaultClass)) {
return 's';
} else if (~string.indexOf(types.number.defaultClass)) {
return 'n';
} else if (~string.indexOf(types.boolean.defaultClass)) {
return 'b';
} else if (~string.indexOf(types.date.defaultClass)) {
return 'd';
} else {
return '';
}
},
/**
* Formats datetimes for compatibility with Excel
* @memberof TableExport.prototype
* @param v {Number}
* @param date1904 {Date}
* @returns {Number} epoch time
*/
dateNum: function (v, date1904) {
if (date1904) v += 1462;
var epoch = Date.parse(v);
return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
},
/**
* Creates an Excel spreadsheet from a data string
* @memberof TableExport.prototype
* @param data {String}
*/
createSheet: function (data) {
var ws = {};
var range = {s: {c: 10000000, r: 10000000}, e: {c: 0, r: 0}};
var types = TableExport.prototype.types;
for (var R = 0; R !== data.length; ++R) {
for (var C = 0; C !== data[R].length; ++C) {
if (range.s.r > R) range.s.r = R;
if (range.s.c > C) range.s.c = C;
if (range.e.r < R) range.e.r = R;
if (range.e.c < C) range.e.c = C;
var cell = data[R][C];
if (!cell || !cell.v) continue;
var cell_ref = XLSX.utils.encode_cell({c: C, r: R});
if (!cell.t) {
if (types.number.assert(cell.v)) cell.t = 'n';
else if (types.boolean.assert(cell.v)) cell.t = 'b';
else if (types.date.assert(cell.v)) cell.t = 'd';
else cell.t = 's';
}
if (cell.t === 'd') {
cell.t = 'n';
cell.z = XLSX.SSF._table[14];
cell.v = this.dateNum(cell.v);
}
ws[cell_ref] = cell;
}
}
if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
return ws;
},
/**
* Excel Workbook constructor
* @memberof TableExport.prototype
* @constructor
*/
Workbook: function () {
this.SheetNames = [];
this.Sheets = {};
},
/**
* Converts a string to an arraybuffer
* @param s {String}
* @memberof TableExport.prototype
* @returns {ArrayBuffer}
*/
string2ArrayBuffer: function (s) {
var buf = new ArrayBuffer(s.length);
var view = new Uint8Array(buf);
for (var i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
return buf;
},
/**
* Exports and downloads the file
* @memberof TableExport.prototype
* @param data {String}
* @param mime {String} mime type
* @param name {String} filename
* @param extension {String} file extension
*/
export2file: function (data, mime, name, extension) {
if (XLSX && extension.substr(0, 4) === (".xls")) {
var wb = new this.Workbook(),
ws = this.createSheet(data);
wb.SheetNames.push(name);
wb.Sheets[name] = ws;
var wopts = {
bookType: extension.substr(1, 3) + (extension.substr(4) || 'm'),
bookSST: false,
type: 'binary'
},
wbout = XLSX.write(wb, wopts);
data = this.string2ArrayBuffer(wbout);
}
saveAs(new Blob([data],
{type: mime + ";" + this.charset}),
name + extension, true);
},
/**
* Updates the plugin instance with new/updated options
* @param options {Object} TableExport configuration options
* @returns {TableExport} updated TableExport instance
*/
update: function (options) {
return new TableExport(this.selectors, $.extend({}, this.settings, options), true);
},
/**
* Reset the plugin instance to its original state
* @returns {TableExport} original TableExport instance
*/
reset: function () {
return new TableExport(this.selectors, this.settings, true);
},
/**
* Remove the instance (i.e. caption containing the export buttons)
*/
remove: function () {
this.selectors.each(function () {
$(this).find('caption:not(.head)').remove();
});
}
};
/**
* jQuery TableExport wrapper
* @param options {Object} TableExport configuration options
* @param isUpdate {Boolean}
* @returns {TableExport} TableExport instance
*/
$.fn.tableExport = function (options, isUpdate) {
return new TableExport(this, options, isUpdate);
};
// alias the TableExport prototype
for (var prop in TableExport.prototype) {
$.fn.tableExport[prop] = TableExport.prototype[prop];
}
return exports.default = exports.TableExport = TableExport;
}
));

File diff suppressed because one or more lines are too long