LaravelTest
1441 строка · 44.5 Кб
1/*!
2* Flash export buttons for Buttons and DataTables.
3* 2015 SpryMedia Ltd - datatables.net/license
4*
5* ZeroClipbaord - MIT license
6* Copyright (c) 2012 Joseph Huckaby
7*/
8
9(function( factory ){10if ( typeof define === 'function' && define.amd ) {11// AMD12define( ['jquery', 'datatables.net', 'datatables.net-buttons'], function ( $ ) {13return factory( $, window, document );14} );15}16else if ( typeof exports === 'object' ) {17// CommonJS18module.exports = function (root, $) {19if ( ! root ) {20root = window;21}22
23if ( ! $ || ! $.fn.dataTable ) {24$ = require('datatables.net')(root, $).$;25}26
27if ( ! $.fn.dataTable.Buttons ) {28require('datatables.net-buttons')(root, $);29}30
31return factory( $, root, root.document );32};33}34else {35// Browser36factory( jQuery, window, document );37}38}(function( $, window, document, undefined ) {39'use strict';40var DataTable = $.fn.dataTable;41
42
43/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
44* ZeroClipboard dependency
45*/
46
47/*
48* ZeroClipboard 1.0.4 with modifications
49* Author: Joseph Huckaby
50* License: MIT
51*
52* Copyright (c) 2012 Joseph Huckaby
53*/
54var ZeroClipboard_TableTools = {55version: "1.0.4-TableTools2",56clients: {}, // registered upload clients on page, indexed by id57moviePath: '', // URL to movie58nextId: 1, // ID of next movie59
60$: function(thingy) {61// simple DOM lookup utility function62if (typeof(thingy) == 'string') {63thingy = document.getElementById(thingy);64}65if (!thingy.addClass) {66// extend element with a few useful methods67thingy.hide = function() { this.style.display = 'none'; };68thingy.show = function() { this.style.display = ''; };69thingy.addClass = function(name) { this.removeClass(name); this.className += ' ' + name; };70thingy.removeClass = function(name) {71this.className = this.className.replace( new RegExp("\\s*" + name + "\\s*"), " ").replace(/^\s+/, '').replace(/\s+$/, '');72};73thingy.hasClass = function(name) {74return !!this.className.match( new RegExp("\\s*" + name + "\\s*") );75};76}77return thingy;78},79
80setMoviePath: function(path) {81// set path to ZeroClipboard.swf82this.moviePath = path;83},84
85dispatch: function(id, eventName, args) {86// receive event from flash movie, send to client87var client = this.clients[id];88if (client) {89client.receiveEvent(eventName, args);90}91},92
93log: function ( str ) {94console.log( 'Flash: '+str );95},96
97register: function(id, client) {98// register new client to receive events99this.clients[id] = client;100},101
102getDOMObjectPosition: function(obj) {103// get absolute coordinates for dom element104var info = {105left: 0,106top: 0,107width: obj.width ? obj.width : obj.offsetWidth,108height: obj.height ? obj.height : obj.offsetHeight109};110
111if ( obj.style.width !== "" ) {112info.width = obj.style.width.replace("px","");113}114
115if ( obj.style.height !== "" ) {116info.height = obj.style.height.replace("px","");117}118
119while (obj) {120info.left += obj.offsetLeft;121info.top += obj.offsetTop;122obj = obj.offsetParent;123}124
125return info;126},127
128Client: function(elem) {129// constructor for new simple upload client130this.handlers = {};131
132// unique ID133this.id = ZeroClipboard_TableTools.nextId++;134this.movieId = 'ZeroClipboard_TableToolsMovie_' + this.id;135
136// register client with singleton to receive flash events137ZeroClipboard_TableTools.register(this.id, this);138
139// create movie140if (elem) {141this.glue(elem);142}143}144};145
146ZeroClipboard_TableTools.Client.prototype = {147
148id: 0, // unique ID for us149ready: false, // whether movie is ready to receive events or not150movie: null, // reference to movie object151clipText: '', // text to copy to clipboard152fileName: '', // default file save name153action: 'copy', // action to perform154handCursorEnabled: true, // whether to show hand cursor, or default pointer cursor155cssEffects: true, // enable CSS mouse effects on dom container156handlers: null, // user event handlers157sized: false,158sheetName: '', // default sheet name for excel export159
160glue: function(elem, title) {161// glue to DOM element162// elem can be ID or actual DOM element object163this.domElement = ZeroClipboard_TableTools.$(elem);164
165// float just above object, or zIndex 99 if dom element isn't set166var zIndex = 99;167if (this.domElement.style.zIndex) {168zIndex = parseInt(this.domElement.style.zIndex, 10) + 1;169}170
171// find X/Y position of domElement172var box = ZeroClipboard_TableTools.getDOMObjectPosition(this.domElement);173
174// create floating DIV above element175this.div = document.createElement('div');176var style = this.div.style;177style.position = 'absolute';178style.left = '0px';179style.top = '0px';180style.width = (box.width) + 'px';181style.height = box.height + 'px';182style.zIndex = zIndex;183
184if ( typeof title != "undefined" && title !== "" ) {185this.div.title = title;186}187if ( box.width !== 0 && box.height !== 0 ) {188this.sized = true;189}190
191// style.backgroundColor = '#f00'; // debug192if ( this.domElement ) {193this.domElement.appendChild(this.div);194this.div.innerHTML = this.getHTML( box.width, box.height ).replace(/&/g, '&');195}196},197
198positionElement: function() {199var box = ZeroClipboard_TableTools.getDOMObjectPosition(this.domElement);200var style = this.div.style;201
202style.position = 'absolute';203//style.left = (this.domElement.offsetLeft)+'px';204//style.top = this.domElement.offsetTop+'px';205style.width = box.width + 'px';206style.height = box.height + 'px';207
208if ( box.width !== 0 && box.height !== 0 ) {209this.sized = true;210} else {211return;212}213
214var flash = this.div.childNodes[0];215flash.width = box.width;216flash.height = box.height;217},218
219getHTML: function(width, height) {220// return HTML for movie221var html = '';222var flashvars = 'id=' + this.id +223'&width=' + width +224'&height=' + height;225
226if (navigator.userAgent.match(/MSIE/)) {227// IE gets an OBJECT tag228var protocol = location.href.match(/^https/i) ? 'https://' : 'http://';229html += '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="'+protocol+'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=10,0,0,0" width="'+width+'" height="'+height+'" id="'+this.movieId+'" align="middle"><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="false" /><param name="movie" value="'+ZeroClipboard_TableTools.moviePath+'" /><param name="loop" value="false" /><param name="menu" value="false" /><param name="quality" value="best" /><param name="bgcolor" value="#ffffff" /><param name="flashvars" value="'+flashvars+'"/><param name="wmode" value="transparent"/></object>';230}231else {232// all other browsers get an EMBED tag233html += '<embed id="'+this.movieId+'" src="'+ZeroClipboard_TableTools.moviePath+'" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="'+width+'" height="'+height+'" name="'+this.movieId+'" align="middle" allowScriptAccess="always" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="'+flashvars+'" wmode="transparent" />';234}235return html;236},237
238hide: function() {239// temporarily hide floater offscreen240if (this.div) {241this.div.style.left = '-2000px';242}243},244
245show: function() {246// show ourselves after a call to hide()247this.reposition();248},249
250destroy: function() {251// destroy control and floater252var that = this;253
254if (this.domElement && this.div) {255$(this.div).remove();256
257this.domElement = null;258this.div = null;259
260$.each( ZeroClipboard_TableTools.clients, function ( id, client ) {261if ( client === that ) {262delete ZeroClipboard_TableTools.clients[ id ];263}264} );265}266},267
268reposition: function(elem) {269// reposition our floating div, optionally to new container270// warning: container CANNOT change size, only position271if (elem) {272this.domElement = ZeroClipboard_TableTools.$(elem);273if (!this.domElement) {274this.hide();275}276}277
278if (this.domElement && this.div) {279var box = ZeroClipboard_TableTools.getDOMObjectPosition(this.domElement);280var style = this.div.style;281style.left = '' + box.left + 'px';282style.top = '' + box.top + 'px';283}284},285
286clearText: function() {287// clear the text to be copy / saved288this.clipText = '';289if (this.ready) {290this.movie.clearText();291}292},293
294appendText: function(newText) {295// append text to that which is to be copied / saved296this.clipText += newText;297if (this.ready) { this.movie.appendText(newText) ;}298},299
300setText: function(newText) {301// set text to be copied to be copied / saved302this.clipText = newText;303if (this.ready) { this.movie.setText(newText) ;}304},305
306setFileName: function(newText) {307// set the file name308this.fileName = newText;309if (this.ready) {310this.movie.setFileName(newText);311}312},313
314setSheetData: function(data) {315// set the xlsx sheet data316if (this.ready) {317this.movie.setSheetData( JSON.stringify( data ) );318}319},320
321setAction: function(newText) {322// set action (save or copy)323this.action = newText;324if (this.ready) {325this.movie.setAction(newText);326}327},328
329addEventListener: function(eventName, func) {330// add user event listener for event331// event types: load, queueStart, fileStart, fileComplete, queueComplete, progress, error, cancel332eventName = eventName.toString().toLowerCase().replace(/^on/, '');333if (!this.handlers[eventName]) {334this.handlers[eventName] = [];335}336this.handlers[eventName].push(func);337},338
339setHandCursor: function(enabled) {340// enable hand cursor (true), or default arrow cursor (false)341this.handCursorEnabled = enabled;342if (this.ready) {343this.movie.setHandCursor(enabled);344}345},346
347setCSSEffects: function(enabled) {348// enable or disable CSS effects on DOM container349this.cssEffects = !!enabled;350},351
352receiveEvent: function(eventName, args) {353var self;354
355// receive event from flash356eventName = eventName.toString().toLowerCase().replace(/^on/, '');357
358// special behavior for certain events359switch (eventName) {360case 'load':361// movie claims it is ready, but in IE this isn't always the case...362// bug fix: Cannot extend EMBED DOM elements in Firefox, must use traditional function363this.movie = document.getElementById(this.movieId);364if (!this.movie) {365self = this;366setTimeout( function() { self.receiveEvent('load', null); }, 1 );367return;368}369
370// firefox on pc needs a "kick" in order to set these in certain cases371if (!this.ready && navigator.userAgent.match(/Firefox/) && navigator.userAgent.match(/Windows/)) {372self = this;373setTimeout( function() { self.receiveEvent('load', null); }, 100 );374this.ready = true;375return;376}377
378this.ready = true;379this.movie.clearText();380this.movie.appendText( this.clipText );381this.movie.setFileName( this.fileName );382this.movie.setAction( this.action );383this.movie.setHandCursor( this.handCursorEnabled );384break;385
386case 'mouseover':387if (this.domElement && this.cssEffects) {388//this.domElement.addClass('hover');389if (this.recoverActive) {390this.domElement.addClass('active');391}392}393break;394
395case 'mouseout':396if (this.domElement && this.cssEffects) {397this.recoverActive = false;398if (this.domElement.hasClass('active')) {399this.domElement.removeClass('active');400this.recoverActive = true;401}402//this.domElement.removeClass('hover');403}404break;405
406case 'mousedown':407if (this.domElement && this.cssEffects) {408this.domElement.addClass('active');409}410break;411
412case 'mouseup':413if (this.domElement && this.cssEffects) {414this.domElement.removeClass('active');415this.recoverActive = false;416}417break;418} // switch eventName419
420if (this.handlers[eventName]) {421for (var idx = 0, len = this.handlers[eventName].length; idx < len; idx++) {422var func = this.handlers[eventName][idx];423
424if (typeof(func) == 'function') {425// actual function reference426func(this, args);427}428else if ((typeof(func) == 'object') && (func.length == 2)) {429// PHP style object + method, i.e. [myObject, 'myMethod']430func[0][ func[1] ](this, args);431}432else if (typeof(func) == 'string') {433// name of function434window[func](this, args);435}436} // foreach event handler defined437} // user defined handler for event438}439};440
441ZeroClipboard_TableTools.hasFlash = function ()442{
443try {444var fo = new ActiveXObject('ShockwaveFlash.ShockwaveFlash');445if (fo) {446return true;447}448}449catch (e) {450if (451navigator.mimeTypes &&452navigator.mimeTypes['application/x-shockwave-flash'] !== undefined &&453navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin454) {455return true;456}457}458
459return false;460};461
462// For the Flash binding to work, ZeroClipboard_TableTools must be on the global
463// object list
464window.ZeroClipboard_TableTools = ZeroClipboard_TableTools;465
466
467
468/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
469* Local (private) functions
470*/
471
472/**
473* If a Buttons instance is initlaised before it is placed into the DOM, Flash
474* won't be able to bind to it, so we need to wait until it is available, this
475* method abstracts that out.
476*
477* @param {ZeroClipboard} flash ZeroClipboard instance
478* @param {jQuery} node Button
479*/
480var _glue = function ( flash, node )481{
482var id = node.attr('id');483
484if ( node.parents('html').length ) {485flash.glue( node[0], '' );486}487else {488setTimeout( function () {489_glue( flash, node );490}, 500 );491}492};493
494/**
495* Get the file name for an exported file.
496*
497* @param {object} config Button configuration
498* @param {boolean} incExtension Include the file name extension
499*/
500var _filename = function ( config, incExtension )501{
502// Backwards compatibility503var filename = config.filename === '*' && config.title !== '*' && config.title !== undefined ?504config.title :505config.filename;506
507if ( typeof filename === 'function' ) {508filename = filename();509}510
511if ( filename.indexOf( '*' ) !== -1 ) {512filename = $.trim( filename.replace( '*', $('title').text() ) );513}514
515// Strip characters which the OS will object to516filename = filename.replace(/[^a-zA-Z0-9_\u00A1-\uFFFF\.,\-_ !\(\)]/g, "");517
518return incExtension === undefined || incExtension === true ?519filename+config.extension :520filename;521};522
523/**
524* Get the sheet name for Excel exports.
525*
526* @param {object} config Button configuration
527*/
528var _sheetname = function ( config )529{
530var sheetName = 'Sheet1';531
532if ( config.sheetName ) {533sheetName = config.sheetName.replace(/[\[\]\*\/\\\?\:]/g, '');534}535
536return sheetName;537};538
539/**
540* Get the title for an exported file.
541*
542* @param {object} config Button configuration
543*/
544var _title = function ( config )545{
546var title = config.title;547
548if ( typeof title === 'function' ) {549title = title();550}551
552return title.indexOf( '*' ) !== -1 ?553title.replace( '*', $('title').text() || 'Exported data' ) :554title;555};556
557/**
558* Set the flash text. This has to be broken up into chunks as the Javascript /
559* Flash bridge has a size limit. There is no indication in the Flash
560* documentation what this is, and it probably depends upon the browser.
561* Experimentation shows that the point is around 50k when data starts to get
562* lost, so an 8K limit used here is safe.
563*
564* @param {ZeroClipboard} flash ZeroClipboard instance
565* @param {string} data Data to send to Flash
566*/
567var _setText = function ( flash, data )568{
569var parts = data.match(/[\s\S]{1,8192}/g) || [];570
571flash.clearText();572for ( var i=0, len=parts.length ; i<len ; i++ )573{574flash.appendText( parts[i] );575}576};577
578/**
579* Get the newline character(s)
580*
581* @param {object} config Button configuration
582* @return {string} Newline character
583*/
584var _newLine = function ( config )585{
586return config.newline ?587config.newline :588navigator.userAgent.match(/Windows/) ?589'\r\n' :590'\n';591};592
593/**
594* Combine the data from the `buttons.exportData` method into a string that
595* will be used in the export file.
596*
597* @param {DataTable.Api} dt DataTables API instance
598* @param {object} config Button configuration
599* @return {object} The data to export
600*/
601var _exportData = function ( dt, config )602{
603var newLine = _newLine( config );604var data = dt.buttons.exportData( config.exportOptions );605var boundary = config.fieldBoundary;606var separator = config.fieldSeparator;607var reBoundary = new RegExp( boundary, 'g' );608var escapeChar = config.escapeChar !== undefined ?609config.escapeChar :610'\\';611var join = function ( a ) {612var s = '';613
614// If there is a field boundary, then we might need to escape it in615// the source data616for ( var i=0, ien=a.length ; i<ien ; i++ ) {617if ( i > 0 ) {618s += separator;619}620
621s += boundary ?622boundary + ('' + a[i]).replace( reBoundary, escapeChar+boundary ) + boundary :623a[i];624}625
626return s;627};628
629var header = config.header ? join( data.header )+newLine : '';630var footer = config.footer && data.footer ? newLine+join( data.footer ) : '';631var body = [];632
633for ( var i=0, ien=data.body.length ; i<ien ; i++ ) {634body.push( join( data.body[i] ) );635}636
637return {638str: header + body.join( newLine ) + footer,639rows: body.length640};641};642
643
644// Basic initialisation for the buttons is common between them
645var flashButton = {646available: function () {647return ZeroClipboard_TableTools.hasFlash();648},649
650init: function ( dt, button, config ) {651// Insert the Flash movie652ZeroClipboard_TableTools.moviePath = DataTable.Buttons.swfPath;653var flash = new ZeroClipboard_TableTools.Client();654
655flash.setHandCursor( true );656flash.addEventListener('mouseDown', function(client) {657config._fromFlash = true;658dt.button( button[0] ).trigger();659config._fromFlash = false;660} );661
662_glue( flash, button );663
664config._flash = flash;665},666
667destroy: function ( dt, button, config ) {668config._flash.destroy();669},670
671fieldSeparator: ',',672
673fieldBoundary: '"',674
675exportOptions: {},676
677title: '*',678
679filename: '*',680
681extension: '.csv',682
683header: true,684
685footer: false686};687
688
689/**
690* Convert from numeric position to letter for column names in Excel
691* @param {int} n Column number
692* @return {string} Column letter(s) name
693*/
694function createCellPos( n ){695var ordA = 'A'.charCodeAt(0);696var ordZ = 'Z'.charCodeAt(0);697var len = ordZ - ordA + 1;698var s = "";699
700while( n >= 0 ) {701s = String.fromCharCode(n % len + ordA) + s;702n = Math.floor(n / len) - 1;703}704
705return s;706}
707
708/**
709* Create an XML node and add any children, attributes, etc without needing to
710* be verbose in the DOM.
711*
712* @param {object} doc XML document
713* @param {string} nodeName Node name
714* @param {object} opts Options - can be `attr` (attributes), `children`
715* (child nodes) and `text` (text content)
716* @return {node} Created node
717*/
718function _createNode( doc, nodeName, opts ){719var tempNode = doc.createElement( nodeName );720
721if ( opts ) {722if ( opts.attr ) {723$(tempNode).attr( opts.attr );724}725
726if( opts.children ) {727$.each( opts.children, function ( key, value ) {728tempNode.appendChild( value );729});730}731
732if( opts.text ) {733tempNode.appendChild( doc.createTextNode( opts.text ) );734}735}736
737return tempNode;738}
739
740/**
741* Get the width for an Excel column based on the contents of that column
742* @param {object} data Data for export
743* @param {int} col Column index
744* @return {int} Column width
745*/
746function _excelColWidth( data, col ) {747var max = data.header[col].length;748var len, lineSplit, str;749
750if ( data.footer && data.footer[col].length > max ) {751max = data.footer[col].length;752}753
754for ( var i=0, ien=data.body.length ; i<ien ; i++ ) {755var point = data.body[i][col];756str = point !== null && point !== undefined ?757point.toString() :758'';759
760// If there is a newline character, workout the width of the column761// based on the longest line in the string762if ( str.indexOf('\n') !== -1 ) {763lineSplit = str.split('\n');764lineSplit.sort( function (a, b) {765return b.length - a.length;766} );767
768len = lineSplit[0].length;769}770else {771len = str.length;772}773
774if ( len > max ) {775max = len;776}777
778// Max width rather than having potentially massive column widths779if ( max > 40 ) {780return 52; // 40 * 1.3781}782}783
784max *= 1.3;785
786// And a min width787return max > 6 ? max : 6;788}
789
790var _serialiser = "";791if (typeof window.XMLSerializer === 'undefined') {792_serialiser = new function () {793this.serializeToString = function (input) {794return input.xml795}796};797} else {798_serialiser = new XMLSerializer();799}800
801var _ieExcel;802
803
804/**
805* Convert XML documents in an object to strings
806* @param {object} obj XLSX document object
807*/
808function _xlsxToStrings( obj ) {809if ( _ieExcel === undefined ) {810// Detect if we are dealing with IE's _awful_ serialiser by seeing if it811// drop attributes812_ieExcel = _serialiser813.serializeToString(814$.parseXML( excelStrings['xl/worksheets/sheet1.xml'] )815)816.indexOf( 'xmlns:r' ) === -1;817}818
819$.each( obj, function ( name, val ) {820if ( $.isPlainObject( val ) ) {821_xlsxToStrings( val );822}823else {824if ( _ieExcel ) {825// IE's XML serialiser will drop some name space attributes from826// from the root node, so we need to save them. Do this by827// replacing the namespace nodes with a regular attribute that828// we convert back when serialised. Edge does not have this829// issue830var worksheet = val.childNodes[0];831var i, ien;832var attrs = [];833
834for ( i=worksheet.attributes.length-1 ; i>=0 ; i-- ) {835var attrName = worksheet.attributes[i].nodeName;836var attrValue = worksheet.attributes[i].nodeValue;837
838if ( attrName.indexOf( ':' ) !== -1 ) {839attrs.push( { name: attrName, value: attrValue } );840
841worksheet.removeAttribute( attrName );842}843}844
845for ( i=0, ien=attrs.length ; i<ien ; i++ ) {846var attr = val.createAttribute( attrs[i].name.replace( ':', '_dt_b_namespace_token_' ) );847attr.value = attrs[i].value;848worksheet.setAttributeNode( attr );849}850}851
852var str = _serialiser.serializeToString(val);853
854// Fix IE's XML855if ( _ieExcel ) {856// IE doesn't include the XML declaration857if ( str.indexOf( '<?xml' ) === -1 ) {858str = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+str;859}860
861// Return namespace attributes to being as such862str = str.replace( /_dt_b_namespace_token_/g, ':' );863}864
865// Safari, IE and Edge will put empty name space attributes onto866// various elements making them useless. This strips them out867str = str.replace( /<([^<>]*?) xmlns=""([^<>]*?)>/g, '<$1 $2>' );868
869obj[ name ] = str;870}871} );872}
873
874// Excel - Pre-defined strings to build a basic XLSX file
875var excelStrings = {876"_rels/.rels":877'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+878'<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">'+879'<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>'+880'</Relationships>',881
882"xl/_rels/workbook.xml.rels":883'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+884'<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">'+885'<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet1.xml"/>'+886'<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>'+887'</Relationships>',888
889"[Content_Types].xml":890'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+891'<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">'+892'<Default Extension="xml" ContentType="application/xml" />'+893'<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml" />'+894'<Default Extension="jpeg" ContentType="image/jpeg" />'+895'<Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml" />'+896'<Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml" />'+897'<Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml" />'+898'</Types>',899
900"xl/workbook.xml":901'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+902'<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">'+903'<fileVersion appName="xl" lastEdited="5" lowestEdited="5" rupBuild="24816"/>'+904'<workbookPr showInkAnnotation="0" autoCompressPictures="0"/>'+905'<bookViews>'+906'<workbookView xWindow="0" yWindow="0" windowWidth="25600" windowHeight="19020" tabRatio="500"/>'+907'</bookViews>'+908'<sheets>'+909'<sheet name="" sheetId="1" r:id="rId1"/>'+910'</sheets>'+911'</workbook>',912
913"xl/worksheets/sheet1.xml":914'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+915'<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">'+916'<sheetData/>'+917'</worksheet>',918
919"xl/styles.xml":920'<?xml version="1.0" encoding="UTF-8"?>'+921'<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">'+922'<numFmts count="6">'+923'<numFmt numFmtId="164" formatCode="#,##0.00_-\ [$$-45C]"/>'+924'<numFmt numFmtId="165" formatCode=""£"#,##0.00"/>'+925'<numFmt numFmtId="166" formatCode="[$€-2]\ #,##0.00"/>'+926'<numFmt numFmtId="167" formatCode="0.0%"/>'+927'<numFmt numFmtId="168" formatCode="#,##0;(#,##0)"/>'+928'<numFmt numFmtId="169" formatCode="#,##0.00;(#,##0.00)"/>'+929'</numFmts>'+930'<fonts count="5" x14ac:knownFonts="1">'+931'<font>'+932'<sz val="11" />'+933'<name val="Calibri" />'+934'</font>'+935'<font>'+936'<sz val="11" />'+937'<name val="Calibri" />'+938'<color rgb="FFFFFFFF" />'+939'</font>'+940'<font>'+941'<sz val="11" />'+942'<name val="Calibri" />'+943'<b />'+944'</font>'+945'<font>'+946'<sz val="11" />'+947'<name val="Calibri" />'+948'<i />'+949'</font>'+950'<font>'+951'<sz val="11" />'+952'<name val="Calibri" />'+953'<u />'+954'</font>'+955'</fonts>'+956'<fills count="6">'+957'<fill>'+958'<patternFill patternType="none" />'+959'</fill>'+960'<fill/>'+ // Excel appears to use this as a dotted background regardless of values961'<fill>'+962'<patternFill patternType="solid">'+963'<fgColor rgb="FFD9D9D9" />'+964'<bgColor indexed="64" />'+965'</patternFill>'+966'</fill>'+967'<fill>'+968'<patternFill patternType="solid">'+969'<fgColor rgb="FFD99795" />'+970'<bgColor indexed="64" />'+971'</patternFill>'+972'</fill>'+973'<fill>'+974'<patternFill patternType="solid">'+975'<fgColor rgb="ffc6efce" />'+976'<bgColor indexed="64" />'+977'</patternFill>'+978'</fill>'+979'<fill>'+980'<patternFill patternType="solid">'+981'<fgColor rgb="ffc6cfef" />'+982'<bgColor indexed="64" />'+983'</patternFill>'+984'</fill>'+985'</fills>'+986'<borders count="2">'+987'<border>'+988'<left />'+989'<right />'+990'<top />'+991'<bottom />'+992'<diagonal />'+993'</border>'+994'<border diagonalUp="false" diagonalDown="false">'+995'<left style="thin">'+996'<color auto="1" />'+997'</left>'+998'<right style="thin">'+999'<color auto="1" />'+1000'</right>'+1001'<top style="thin">'+1002'<color auto="1" />'+1003'</top>'+1004'<bottom style="thin">'+1005'<color auto="1" />'+1006'</bottom>'+1007'<diagonal />'+1008'</border>'+1009'</borders>'+1010'<cellStyleXfs count="1">'+1011'<xf numFmtId="0" fontId="0" fillId="0" borderId="0" />'+1012'</cellStyleXfs>'+1013'<cellXfs count="61">'+1014'<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+1015'<xf numFmtId="0" fontId="1" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+1016'<xf numFmtId="0" fontId="2" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+1017'<xf numFmtId="0" fontId="3" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+1018'<xf numFmtId="0" fontId="4" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+1019'<xf numFmtId="0" fontId="0" fillId="2" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+1020'<xf numFmtId="0" fontId="1" fillId="2" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+1021'<xf numFmtId="0" fontId="2" fillId="2" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+1022'<xf numFmtId="0" fontId="3" fillId="2" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+1023'<xf numFmtId="0" fontId="4" fillId="2" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+1024'<xf numFmtId="0" fontId="0" fillId="3" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+1025'<xf numFmtId="0" fontId="1" fillId="3" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+1026'<xf numFmtId="0" fontId="2" fillId="3" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+1027'<xf numFmtId="0" fontId="3" fillId="3" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+1028'<xf numFmtId="0" fontId="4" fillId="3" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+1029'<xf numFmtId="0" fontId="0" fillId="4" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+1030'<xf numFmtId="0" fontId="1" fillId="4" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+1031'<xf numFmtId="0" fontId="2" fillId="4" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+1032'<xf numFmtId="0" fontId="3" fillId="4" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+1033'<xf numFmtId="0" fontId="4" fillId="4" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+1034'<xf numFmtId="0" fontId="0" fillId="5" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+1035'<xf numFmtId="0" fontId="1" fillId="5" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+1036'<xf numFmtId="0" fontId="2" fillId="5" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+1037'<xf numFmtId="0" fontId="3" fillId="5" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+1038'<xf numFmtId="0" fontId="4" fillId="5" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+1039'<xf numFmtId="0" fontId="0" fillId="0" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+1040'<xf numFmtId="0" fontId="1" fillId="0" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+1041'<xf numFmtId="0" fontId="2" fillId="0" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+1042'<xf numFmtId="0" fontId="3" fillId="0" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+1043'<xf numFmtId="0" fontId="4" fillId="0" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+1044'<xf numFmtId="0" fontId="0" fillId="2" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+1045'<xf numFmtId="0" fontId="1" fillId="2" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+1046'<xf numFmtId="0" fontId="2" fillId="2" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+1047'<xf numFmtId="0" fontId="3" fillId="2" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+1048'<xf numFmtId="0" fontId="4" fillId="2" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+1049'<xf numFmtId="0" fontId="0" fillId="3" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+1050'<xf numFmtId="0" fontId="1" fillId="3" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+1051'<xf numFmtId="0" fontId="2" fillId="3" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+1052'<xf numFmtId="0" fontId="3" fillId="3" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+1053'<xf numFmtId="0" fontId="4" fillId="3" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+1054'<xf numFmtId="0" fontId="0" fillId="4" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+1055'<xf numFmtId="0" fontId="1" fillId="4" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+1056'<xf numFmtId="0" fontId="2" fillId="4" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+1057'<xf numFmtId="0" fontId="3" fillId="4" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+1058'<xf numFmtId="0" fontId="4" fillId="4" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+1059'<xf numFmtId="0" fontId="0" fillId="5" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+1060'<xf numFmtId="0" fontId="1" fillId="5" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+1061'<xf numFmtId="0" fontId="2" fillId="5" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+1062'<xf numFmtId="0" fontId="3" fillId="5" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+1063'<xf numFmtId="0" fontId="4" fillId="5" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+1064'<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">'+1065'<alignment horizontal="left"/>'+1066'</xf>'+1067'<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">'+1068'<alignment horizontal="center"/>'+1069'</xf>'+1070'<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">'+1071'<alignment horizontal="right"/>'+1072'</xf>'+1073'<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">'+1074'<alignment horizontal="fill"/>'+1075'</xf>'+1076'<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">'+1077'<alignment textRotation="90"/>'+1078'</xf>'+1079'<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">'+1080'<alignment wrapText="1"/>'+1081'</xf>'+1082'<xf numFmtId="9" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+1083'<xf numFmtId="164" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+1084'<xf numFmtId="165" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+1085'<xf numFmtId="166" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+1086'<xf numFmtId="167" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+1087'<xf numFmtId="168" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+1088'<xf numFmtId="169" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+1089'<xf numFmtId="3" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+1090'<xf numFmtId="4" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+1091'</cellXfs>'+1092'<cellStyles count="1">'+1093'<cellStyle name="Normal" xfId="0" builtinId="0" />'+1094'</cellStyles>'+1095'<dxfs count="0" />'+1096'<tableStyles count="0" defaultTableStyle="TableStyleMedium9" defaultPivotStyle="PivotStyleMedium4" />'+1097'</styleSheet>'1098};1099// Note we could use 3 `for` loops for the styles, but when gzipped there is
1100// virtually no difference in size, since the above can be easily compressed
1101
1102// Pattern matching for special number formats. Perhaps this should be exposed
1103// via an API in future?
1104var _excelSpecials = [1105{ match: /^\-?\d+\.\d%$/, style: 60, fmt: function (d) { return d/100; } }, // Precent with d.p.1106{ match: /^\-?\d+\.?\d*%$/, style: 56, fmt: function (d) { return d/100; } }, // Percent1107{ match: /^\-?\$[\d,]+.?\d*$/, style: 57 }, // Dollars1108{ match: /^\-?£[\d,]+.?\d*$/, style: 58 }, // Pounds1109{ match: /^\-?€[\d,]+.?\d*$/, style: 59 }, // Euros1110{ match: /^\([\d,]+\)$/, style: 61, fmt: function (d) { return -1 * d.replace(/[\(\)]/g, ''); } }, // Negative numbers indicated by brackets1111{ match: /^\([\d,]+\.\d{2}\)$/, style: 62, fmt: function (d) { return -1 * d.replace(/[\(\)]/g, ''); } }, // Negative numbers indicated by brackets - 2d.p.1112{ match: /^[\d,]+$/, style: 63 }, // Numbers with thousand separators1113{ match: /^[\d,]+\.\d{2}$/, style: 64 } // Numbers with 2d.p. and thousands separators1114];1115
1116
1117
1118/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1119* DataTables options and methods
1120*/
1121
1122// Set the default SWF path
1123DataTable.Buttons.swfPath = '//cdn.datatables.net/buttons/1.2.4/swf/flashExport.swf';1124
1125// Method to allow Flash buttons to be resized when made visible - as they are
1126// of zero height and width if initialised hidden
1127DataTable.Api.register( 'buttons.resize()', function () {1128$.each( ZeroClipboard_TableTools.clients, function ( i, client ) {1129if ( client.domElement !== undefined && client.domElement.parentNode ) {1130client.positionElement();1131}1132} );1133} );1134
1135
1136/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1137* Button definitions
1138*/
1139
1140// Copy to clipboard
1141DataTable.ext.buttons.copyFlash = $.extend( {}, flashButton, {1142className: 'buttons-copy buttons-flash',1143
1144text: function ( dt ) {1145return dt.i18n( 'buttons.copy', 'Copy' );1146},1147
1148action: function ( e, dt, button, config ) {1149// Check that the trigger did actually occur due to a Flash activation1150if ( ! config._fromFlash ) {1151return;1152}1153
1154this.processing( true );1155
1156var flash = config._flash;1157var data = _exportData( dt, config );1158var output = config.customize ?1159config.customize( data.str, config ) :1160data.str;1161
1162flash.setAction( 'copy' );1163_setText( flash, output );1164
1165this.processing( false );1166
1167dt.buttons.info(1168dt.i18n( 'buttons.copyTitle', 'Copy to clipboard' ),1169dt.i18n( 'buttons.copySuccess', {1170_: 'Copied %d rows to clipboard',11711: 'Copied 1 row to clipboard'1172}, data.rows ),117330001174);1175},1176
1177fieldSeparator: '\t',1178
1179fieldBoundary: ''1180} );1181
1182// CSV save file
1183DataTable.ext.buttons.csvFlash = $.extend( {}, flashButton, {1184className: 'buttons-csv buttons-flash',1185
1186text: function ( dt ) {1187return dt.i18n( 'buttons.csv', 'CSV' );1188},1189
1190action: function ( e, dt, button, config ) {1191// Set the text1192var flash = config._flash;1193var data = _exportData( dt, config );1194var output = config.customize ?1195config.customize( data.str, config ) :1196data.str;1197
1198flash.setAction( 'csv' );1199flash.setFileName( _filename( config ) );1200_setText( flash, output );1201},1202
1203escapeChar: '"'1204} );1205
1206// Excel save file - this is really a CSV file using UTF-8 that Excel can read
1207DataTable.ext.buttons.excelFlash = $.extend( {}, flashButton, {1208className: 'buttons-excel buttons-flash',1209
1210text: function ( dt ) {1211return dt.i18n( 'buttons.excel', 'Excel' );1212},1213
1214action: function ( e, dt, button, config ) {1215this.processing( true );1216
1217var flash = config._flash;1218var rowPos = 0;1219var rels = $.parseXML( excelStrings['xl/worksheets/sheet1.xml'] ) ; //Parses xml1220var relsGet = rels.getElementsByTagName( "sheetData" )[0];1221
1222var xlsx = {1223_rels: {1224".rels": $.parseXML( excelStrings['_rels/.rels'] )1225},1226xl: {1227_rels: {1228"workbook.xml.rels": $.parseXML( excelStrings['xl/_rels/workbook.xml.rels'] )1229},1230"workbook.xml": $.parseXML( excelStrings['xl/workbook.xml'] ),1231"styles.xml": $.parseXML( excelStrings['xl/styles.xml'] ),1232"worksheets": {1233"sheet1.xml": rels1234}1235
1236},1237"[Content_Types].xml": $.parseXML( excelStrings['[Content_Types].xml'])1238};1239
1240var data = dt.buttons.exportData( config.exportOptions );1241var currentRow, rowNode;1242var addRow = function ( row ) {1243currentRow = rowPos+1;1244rowNode = _createNode( rels, "row", { attr: {r:currentRow} } );1245
1246for ( var i=0, ien=row.length ; i<ien ; i++ ) {1247// Concat both the Cell Columns as a letter and the Row of the cell.1248var cellId = createCellPos(i) + '' + currentRow;1249var cell = null;1250
1251// For null, undefined of blank cell, continue so it doesn't create the _createNode1252if ( row[i] === null || row[i] === undefined || row[i] === '' ) {1253continue;1254}1255
1256row[i] = $.trim( row[i] );1257
1258// Special number formatting options1259for ( var j=0, jen=_excelSpecials.length ; j<jen ; j++ ) {1260var special = _excelSpecials[j];1261
1262// TODO Need to provide the ability for the specials to say1263// if they are returning a string, since at the moment it is1264// assumed to be a number1265if ( row[i].match && ! row[i].match(/^0\d+/) && row[i].match( special.match ) ) {1266var val = row[i].replace(/[^\d\.\-]/g, '');1267
1268if ( special.fmt ) {1269val = special.fmt( val );1270}1271
1272cell = _createNode( rels, 'c', {1273attr: {1274r: cellId,1275s: special.style1276},1277children: [1278_createNode( rels, 'v', { text: val } )1279]1280} );1281
1282break;1283}1284}1285
1286if ( ! cell ) {1287if ( typeof row[i] === 'number' || (1288row[i].match &&1289row[i].match(/^-?\d+(\.\d+)?$/) &&1290! row[i].match(/^0\d+/) )1291) {1292// Detect numbers - don't match numbers with leading zeros1293// or a negative anywhere but the start1294cell = _createNode( rels, 'c', {1295attr: {1296t: 'n',1297r: cellId1298},1299children: [1300_createNode( rels, 'v', { text: row[i] } )1301]1302} );1303}1304else {1305// String output - replace non standard characters for text output1306var text = ! row[i].replace ?1307row[i] :1308row[i].replace(/[\x00-\x09\x0B\x0C\x0E-\x1F\x7F-\x9F]/g, '');1309
1310cell = _createNode( rels, 'c', {1311attr: {1312t: 'inlineStr',1313r: cellId1314},1315children:{1316row: _createNode( rels, 'is', {1317children: {1318row: _createNode( rels, 't', {1319text: text1320} )1321}1322} )1323}1324} );1325}1326}1327
1328rowNode.appendChild( cell );1329}1330
1331relsGet.appendChild(rowNode);1332rowPos++;1333};1334
1335$( 'sheets sheet', xlsx.xl['workbook.xml'] ).attr( 'name', _sheetname( config ) );1336
1337if ( config.customizeData ) {1338config.customizeData( data );1339}1340
1341if ( config.header ) {1342addRow( data.header, rowPos );1343$('row c', rels).attr( 's', '2' ); // bold1344}1345
1346for ( var n=0, ie=data.body.length ; n<ie ; n++ ) {1347addRow( data.body[n], rowPos );1348}1349
1350if ( config.footer && data.footer ) {1351addRow( data.footer, rowPos);1352$('row:last c', rels).attr( 's', '2' ); // bold1353}1354
1355// Set column widths1356var cols = _createNode( rels, 'cols' );1357$('worksheet', rels).prepend( cols );1358
1359for ( var i=0, ien=data.header.length ; i<ien ; i++ ) {1360cols.appendChild( _createNode( rels, 'col', {1361attr: {1362min: i+1,1363max: i+1,1364width: _excelColWidth( data, i ),1365customWidth: 11366}1367} ) );1368}1369
1370// Let the developer customise the document if they want to1371if ( config.customize ) {1372config.customize( xlsx );1373}1374
1375_xlsxToStrings( xlsx );1376
1377flash.setAction( 'excel' );1378flash.setFileName( _filename( config ) );1379flash.setSheetData( xlsx );1380_setText( flash, '' );1381
1382this.processing( false );1383},1384
1385extension: '.xlsx'1386} );1387
1388
1389
1390// PDF export
1391DataTable.ext.buttons.pdfFlash = $.extend( {}, flashButton, {1392className: 'buttons-pdf buttons-flash',1393
1394text: function ( dt ) {1395return dt.i18n( 'buttons.pdf', 'PDF' );1396},1397
1398action: function ( e, dt, button, config ) {1399this.processing( true );1400
1401// Set the text1402var flash = config._flash;1403var data = dt.buttons.exportData( config.exportOptions );1404var totalWidth = dt.table().node().offsetWidth;1405
1406// Calculate the column width ratios for layout of the table in the PDF1407var ratios = dt.columns( config.columns ).indexes().map( function ( idx ) {1408return dt.column( idx ).header().offsetWidth / totalWidth;1409} );1410
1411flash.setAction( 'pdf' );1412flash.setFileName( _filename( config ) );1413
1414_setText( flash, JSON.stringify( {1415title: _filename(config, false),1416message: typeof config.message == 'function' ? config.message(dt, button, config) : config.message,1417colWidth: ratios.toArray(),1418orientation: config.orientation,1419size: config.pageSize,1420header: config.header ? data.header : null,1421footer: config.footer ? data.footer : null,1422body: data.body1423} ) );1424
1425this.processing( false );1426},1427
1428extension: '.pdf',1429
1430orientation: 'portrait',1431
1432pageSize: 'A4',1433
1434message: '',1435
1436newline: '\n'1437} );1438
1439
1440return DataTable.Buttons;1441}));1442