在IE中使用表创建pdf的问题

时间:2017-01-10 19:41:58

标签: javascript html pdf jspdf jspdf-autotable

目前,我使用jspdf最新版本和jspdf-AutoTable 2.1.0 最新版本来创建一个包含非常复杂表格的PDF。

它就像Chrome和FireFox中的魅力一样(大惊喜!)但是在IE10中,它非常好地渲染了pdf(另一个大惊喜!)

这是chrome上pdf中最广泛的表格之一(当前为空)

的输出

PDF generated on Chrome

这是IE10呈现的pdf

enter image description here

正如您所看到的那样,它没有按原样包装列标题,也没有展开并显示第一列单元格并裁剪其中的文本。

为了保留我的自定义表格样式,使用它的内容正确的样式,我调整并创建了自己的$canvas = getCharacterOutline(); $kernel = \ImagickKernel::fromBuiltIn(\Imagick::KERNEL_DISK, "6"); $canvas->morphology(\Imagick::MORPHOLOGY_CLOSE, 1, $kernel); header("Content-Type: image/png"); echo $canvas->getImageBlob(); 方法,因此我可以检索并存储每个单独的单元格样式并稍后应用它GetTableJSONcreatedHeaderCell挂钩

这是用于使用自定义样式创建此pdf的完整代码

createdCell

编辑:

根据要求,这是表格HTML和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; } 变量

的JSON

https://jsfiddle.net/6ewqnwty/

由于表格的大小以及HTML和JSON的字符数量,我将它们设置在一个单独的小提琴中。

编辑2:

我只是让小提琴可以运行,能够重现这个问题。

https://jsfiddle.net/6ewqnwty/1/

我在我的应用程序中没有完美,我能够使用样式检索pdf,只缺少列标题文本,但至少在IE上下载pdf的问题仍然存在

1 个答案:

答案 0 :(得分:2)

运行你的例子我得到了NaN用于cellPadding。这也可能是它无法与最新版本一起使用的原因。你可以做一些简单的事情,比如添加:

cell.styles.cellPadding = styles.cellPadding || 5;
在ApplyCellStyle中

。你得到NaN的原因是IE显然会返回空字符串而不是&#39; 0px&#39;哪个铬等。

另请注意,如果升级,则不需要自己解析html表,因为cell.raw设置为最新版本中的html元素。这意味着您可以使用window.getComputedStyle(cell.raw)

之类的内容来解析样式