現在、非常に複雑なテーブルを含む PDF を作成するために、jspdf 最新バージョンと jspdf-AutoTable 2.1.0最新バージョンを使用しています。
Chrome と FireFox では魅力的に動作します (大きな驚きです!) が、IE10 では、pdf のレンダリングがひどいものです (別の大きな驚きです!)。
これは、chrome 上の pdf で最も広範なテーブルの 1 つの出力です (現在は空です)。
これはIE10がレンダリングするpdfです
ご覧のとおり、列ヘッダーが適切にラップされておらず、最初の列のセルが展開されて表示され、その中のテキストがトリミングされていません。
カスタム テーブル スタイルを維持するために、コンテンツの正しいスタイル設定を使用して、独自のGetTableJSON
メソッドを調整および作成しました。これにより、個々のセル スタイルを取得して保存し、後でcreatedHeaderCell
およびcreatedCell
フックに適用できます。
これは、カスタム スタイルでこの pdf を作成するために使用される完全なコードです。
function DownloadSchedulePDF() {
var orientation = landscape ? 'l' : 'p'
var doc = new jsPDF(orientation, 'pt', paperFormat);
doc.text('Header', 40, 50);
var res = GetTableJSON($(".scheduleGrid table"));
tableCellsStyles = res.styles;
doc.autoTable(res.columns, res.data, {
theme: 'plain',
startY: 60,
pageBreak: 'auto',
margin: 20,
width: 'auto',
styles: {
lineWidth: 0.01,
lineColor: 0,
fillStyle: 'DF',
halign: 'center',
valign: 'middle',
columnWidth: 'auto',
overflow: 'linebreak'
},
createdHeaderCell: function (cell, data) {
ApplyCellStyle(cell, "th", data.column.dataKey);
},
createdCell: function (cell, data) {
ApplyCellStyle(cell, data.row.index, data.column.dataKey);
},
drawHeaderCell: function (cell, data) {
//ApplyCellStyle(cell, "th", data.column.dataKey);
//data.table.headerRow.cells[data.column.dataKey].styles = cell.styles;
//ApplyCellStyle(data.table.headerRow.cells[data.column.dataKey], "th", data.column.dataKey);
},
drawCell: function (cell, data) {
if (cell.raw === undefined)
return false;
if(cell.raw.indexOf("*") > -1) {
var text = cell.raw.split("*")[0];
var times = cell.raw.split("*")[1];
doc.rect(cell.x, cell.y, cell.width, cell.height * times, 'FD');
doc.autoTableText(text, cell.x + cell.width / 2, cell.y + cell.height * times / 2, {
halign: 'center',
valign: 'middle'
});
return false;
}
}
});
doc.save("schedule " + selectedDate.toLocaleDateString() + ".pdf");
}
function ApplyCellStyle(cell, x, y) {
if(!pdfInColor)
return;
var styles = tableCellsStyles[x + "-" + y];
if (styles === undefined)
return;
cell.styles.cellPadding = styles.cellPadding
cell.styles.fillColor = styles.fillColor;
cell.styles.textColor = styles.textColor;
cell.styles.font = styles.font;
cell.styles.fontStyle = styles.fontStyle;
}
Object.vals = function (o) {
return Object.values
? Object.values(o)
: Object.keys(o).map(function (k) { return o[k]; });
}
// direct copy of the plugin method adjusted in order to retrieve and store each cell style
function GetTableJSON (tableElem, includeHiddenElements) {
includeHiddenElements = includeHiddenElements || false;
var columns = {}, rows = [];
var cellsStyle = {};
var header = tableElem.rows[0];
for (var k = 0; k < header.cells.length; k++) {
var cell = header.cells[k];
var style = window.getComputedStyle(cell);
cellsStyle["th-" + k] = AdjustStyleProperties(style);
if (includeHiddenElements || style.display !== 'none') {
columns[k] = cell ? cell.textContent.trim() : '';
}
}
for (var i = 1; i < tableElem.rows.length; i++) {
var tableRow = tableElem.rows[i];
var style = window.getComputedStyle(tableRow);
if (includeHiddenElements || style.display !== 'none') {
var rowData = [];
for (var j in Object.keys(columns)) {
var cell = tableRow.cells[j];
style = window.getComputedStyle(cell);
if (includeHiddenElements || style.display !== 'none') {
var val = cell
? cell.hasChildNodes() && cell.childNodes[0].tagName !== undefined
? cell.childNodes[0].textContent + (cell.getAttribute("rowSpan") ? "*" + cell.getAttribute("rowSpan") : '')
: cell.textContent.trim()
: '';
cellsStyle[(i-1) + "-" + j] = cell
? cell.hasChildNodes() && cell.childNodes[0].tagName !== undefined
? AdjustStyleProperties(window.getComputedStyle(cell.childNodes[0]))
: AdjustStyleProperties(window.getComputedStyle(cell))
: {};
rowData.push(val);
}
}
rows.push(rowData);
}
}
return {columns: Object.vals(columns), rows: rows, data: rows, styles: cellsStyle}; // data prop deprecated
};
function AdjustStyleProperties(style) {
return {
cellPadding: parseInt(style.padding),
fontSize: parseInt(style.fontSize),
font: style.fontFamily, // helvetica, times, courier
lineColor: ConvertToRGB(style.borderColor),
lineWidth: parseInt(style.borderWidth) / 10,
fontStyle: style.fontStyle, // normal, bold, italic, bolditalic
overflow: 'linebreak', // visible, hidden, ellipsize or linebreak
fillColor: ConvertToRGB(style.backgroundColor),
textColor: ConvertToRGB(style.color),
halign: 'center', // left, center, right
valign: 'middle', // top, middle, bottom
fillStyle: 'DF', // 'S', 'F' or 'DF' (stroke, fill or fill then stroke)
rowHeight: parseInt(style.height),
columnWidth: parseInt(style.width) // 'auto', 'wrap' or a number
//columnWidth: 'auto'
};
}
function ConvertToRGB(value) {
if (value === undefined || value === '' || value === "transparent")
value = [255, 255, 255];
else if (value.indexOf("rgb") > -1)
value = value.replace(/[^\d,]/g, '').split(',').map(function (x) { return parseInt(x) });
else if (value.indexOf("#") > -1)
value = value.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i
, function (m, r, g, b) { return '#' + r + r + g + g + b + b })
.substring(1).match(/.{2}/g)
.map(function (x) { return parseInt(x, 16) });
else if (Array.isArray(value))
return value;
else {
var canvas, context;
canvas = document.createElement('canvas');
canvas.height = 1;
canvas.width = 1;
context = canvas.getContext('2d');
context.fillStyle = 'rgba(0, 0, 0, 0)';
// We're reusing the canvas, so fill it with something predictable
context.clearRect(0, 0, 1, 1);
context.fillStyle = value;
context.fillRect(0, 0, 1, 1);
var imgData = context.getImageData(0, 0, 1, 1);
value = imgData.data.slice
? imgData.data.slice(0, 3)
: [imgData.data[0], imgData.data[1], imgData.data[2]];
}
return value;
}
編集:
要求どおり、これはテーブル HTML とtableCellStyles
変数の JSON です
https://jsfiddle.net/6ewqnwty/
テーブルのサイズと HTML と JSON の文字数が多いため、それらを別のフィドルに設定しました。
編集2:
問題を再現できるように、フィドルを実行可能にしました。
https://jsfiddle.net/6ewqnwty/1/
私のアプリケーションにあるように完全ではありませんが、列ヘッダーのテキストのみが欠落しているスタイリングでpdfを取得できますが、少なくともIEでpdfをダウンロードするときの問題はまだ存在しています