Sencha Touch Grind-Printer

Montag, 31. März 2014
Maybe someone of you already had the wish to print a grid easily from within a Sencha Touch application.

Requirements:

  • Cordova
  • Cordova printer plugin: https://github.com/FRD49/phonegap-print-plugin


Here is a short javascript source written by myself to archive this. Documentation is in the code itself. Columns without a dataindex will not be printed!

/**
* @class Ext.ux.grid.Printer
* @author Fabian Diehl (@_FlashLight)
* Helper class to easily print the contents of a grid.
*
* Usage:
*
* 1 - Add Ext.Require Before the Grid code
* Ext.require([
* 'Ext.ux.grid.GridPrinter',
* ]);
*
* 2 - Declare the Grid
* var grid = Ext.create('Ext.grid.Panel', {
* columns: //some column model,
* store : //some store
* });
*
* 3 - Print!
* Ext.ux.grid.Printer.fileName = 'Your Title here'; //optional
* Ext.ux.grid.Printer.fileType = 'text/html'; //optional
* Ext.ux.grid.Printer.landscape = true or false; //optional
* Ext.ux.grid.Printer.successCallback = function(){console.log('Print successfull')}; //optional
* Ext.ux.grid.Printer.failureCallback = function(){console.log('Print failure')}; //optional
* Ext.ux.grid.Printer.print(grid);
*
* Original url: http://edspencer.net/2009/07/printing-grids-with-ext-js.html
*
* Modified by Fabian Diehl (@_FlashLight) - March 2014 - Ported to Sencha Touch 2.3
*/
Ext.define("Ext.ux.grid.Printer", {
requires: 'Ext.XTemplate',
statics: {
/**
* Prints the passed grid. Reflects on the grid's column model to build a table, and fills it using the store
* @param {Ext.grid.Panel} grid The grid to print
*/
print: function (grid) {
//We generate an XTemplate here by using 2 intermediary XTemplates - one to create the header,
//the other to create the body (see the escaped {} below)
var columns = [];
var varReplace = /(^[^a-z]*|[^\w])/gi;
//account for grouped columns
Ext.each(grid.getColumns(), function (c) {
columns.push(c);
});
//build a usable array of store data for the XTemplate
var data = [];
grid.getStore().data.each(function (item, row) {
var convertedData = {};
//apply renderers from column model
Ext.each(columns, function (column, col) {
rowName = column.getDataIndex() || '';
if (rowName !== 'nbsp') {
if (column && column.xtype === 'column' && column.getDataIndex()) {
value = item.get(column.getDataIndex());
convertedData[rowName] = value;
} else if (column && column.xtype === 'templatecolumn') {
value = column.getTpl().apply(item.getData());
convertedData[rowName] = value;
}
}
});
data.push(convertedData);
});
var clearColumns = [];
Ext.each(grid.getColumns(), function (column) {
if (column) {
if (column && column.xtype === 'column' && column.getDataIndex() && !column.hidden) {
clearColumns.push(column);
} else if (column && column.xtype === 'templatecolumn' && column.getText() !== ' ') {
clearColumns.push(column);
}
}
});
columns = clearColumns;
/**
* @property headerTpl
* @type {Object/Array} values
* The markup used to create the headings row. By default this just uses <th> elements, override to provide your own
*/
var headerTpl = Ext.create('Ext.XTemplate',
'<tpl for=".">',
'<th>{[values.getText()]}</th>',
'</tpl>'
);
/**
* @property bodyTpl
* @type {Object/Array} values
* The XTemplate used to create each row. This is used inside the 'print' function to build another XTemplate, to which the data
* are then applied (see the escaped dataIndex attribute here - this ends up as "{dataIndex}")
*/
var bodyTpl = Ext.create('Ext.XTemplate',
'<tpl for=".">',
'<td align="{[values.getAlign()]}">{{[values.getDataIndex()]}}</td>',
'</tpl>'
);
//use the headerTpl and bodyTpl markups to create the main XTemplate below
var headings = headerTpl.apply(columns);
var body = bodyTpl.apply(columns);
var pluginsBody = '',
pluginsBodyMarkup = [];
//add relevant plugins
Ext.each(grid.plugins, function (p) {
if (p.ptype == 'rowexpander') {
pluginsBody += p.rowBodyTpl.join('');
}
});
if (pluginsBody !== '') {
pluginsBodyMarkup = [
'<tr class="{[xindex % 2 === 0 ? "even" : "odd"]}"><td colspan="' + columns.length + '">',
pluginsBody,
'</td></tr>'
];
}
//Here because inline styles using CSS, the browser did not show the correct formatting of the data the first time that loaded
var htmlMarkup = [
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
'<html class="' + Ext.baseCSSPrefix + 'ux-grid-printer">',
'<head>',
'<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />',
'<title>' + grid.title + '</title>',
'<style type="text/css" media="all">',
'.cssPlaceHolder',
'</style>',
'</head>',
'<body class="' + Ext.baseCSSPrefix + 'ux-grid-printer-body">',
'<div class="' + Ext.baseCSSPrefix + 'ux-grid-printer-noprint ' + Ext.baseCSSPrefix + 'ux-grid-printer-links">',
'</div>',
'<h1>' + this.mainTitle + '</h1>',
'<table>',
'<tr>',
headings,
'</tr>',
'<tpl for=".">',
'<tr class="{[xindex % 2 === 0 ? "even" : "odd"]}">',
body,
'</tr>',
pluginsBodyMarkup.join(''),
'</tpl>',
'</table>',
'</body>',
'</html>'
];
var fileContent = Ext.create('Ext.XTemplate', htmlMarkup).apply(data);
var type = this.fileType;
var name = this.fileName;
// TEMP
fileContent = fileContent.replace('.cssPlaceHolder', this.fileCss);
// TEMP
//open up a new printing window, write to it, print it and close
if (window.plugins && window.plugins.PrintPlugin) {
window.plugins.PrintPlugin.print([fileContent,this.landscape], function () {
console.log('success');
}, function () {
console.log('fail');
}, "", type, name);
} else {
Ext.Msg.alert('Printing error', 'Printer plugin not found: window.plugins.PrintPlugin');
}
},
/**
* @property mainTitle
* @type String
* Title to be used on top of the table
* (defaults to empty)
*/
mainTitle: '',
/**
* @property fileName
* @type String
* Filename to be used
* (defaults to index.html)
*/
fileName: 'index.html',
/**
* @property fileType
* @type String
* File type to be used
* (defaults to text/html)
*/
fileType: "text/html",
/**
* @property fileCss
* @type String
* Additional css to be used
* (defaults to some css)
*/
fileCss: '.x-ux-grid-printer blockquote,.x-ux-grid-printer dd,.x-ux-grid-printer div,.x-ux-grid-printer dl,.x-ux-grid-printer dt,.x-ux-grid-printer fieldset,.x-ux-grid-printer form,.x-ux-grid-printer h1,.x-ux-grid-printer h2,.x-ux-grid-printer h3,.x-ux-grid-printer h4,.x-ux-grid-printer h5,.x-ux-grid-printer h6,.x-ux-grid-printer input,.x-ux-grid-printer li,.x-ux-grid-printer ol,.x-ux-grid-printer p,.x-ux-grid-printer pre,.x-ux-grid-printer td,.x-ux-grid-printer th,.x-ux-grid-printer ul,html.x-ux-grid-printer{margin:0;padding:0}.x-ux-grid-printer body,.x-ux-grid-printer img,html.x-ux-grid-printer{border:0}.x-ux-grid-printer address,.x-ux-grid-printer caption,.x-ux-grid-printer cite,.x-ux-grid-printer code,.x-ux-grid-printer dfn,.x-ux-grid-printer em,.x-ux-grid-printer strong,.x-ux-grid-printer th,.x-ux-grid-printer var{font-style:normal;font-weight:400}.x-ux-grid-printer ol,.x-ux-grid-printer ul{list-style:none}.x-ux-grid-printer caption,.x-ux-grid-printer th{text-align:left}.x-ux-grid-printer h1,.x-ux-grid-printer h2,.x-ux-grid-printer h3,.x-ux-grid-printer h4,.x-ux-grid-printer h5,.x-ux-grid-printer h6{font-size:100%}.x-ux-grid-printer .x-ux-grid-printer-links{padding:0 0 20px}.x-ux-grid-printer table{width:100%;text-align:left;font-size:11px;font-family:arial;border-collapse:collapse}.x-ux-grid-printer table th{font-weight:700;padding:4px 3px 4px 5px;border:1px solid #d0d0d0;border-left-color:#eee;background-color:#ededed}.x-ux-grid-printer table tr.odd{background-color:#fff}.x-ux-grid-printer table tr.even{background-color:#f9f9f9}.x-ux-grid-printer table td{padding:4px 3px 4px 5px;border-style:none solid solid;border-width:1px;border-color:#ededed}.rightAlign{text-align: right;}.leftAlign{text-align: left;}.centerAlign{text-align: center;}',
/**
* @property landscape
* @type bool
* Print in landscape mode
* (defaults to false)
*/
landscape: false
}
});
view raw gridprinter.js hosted with ❤ by GitHub

Keine Kommentare:

Kommentar veröffentlichen