- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我使用 JavaScript 插件 ( pdfmake ) 成功创建了一个 PDF,它很棒。但是,当我尝试渲染约 8,000 行的库存/分类帐打印输出时,它会卡住一分钟多。
这就是我通常声明我的 docDefinition 的方式
var docDefinition = {
pageOrientation: orientation,
footer: function(currentPage, pageCount) { return {text: currentPage.toString() + ' / ' + pageCount, fontSize:8, alignment:'center'}; },
content:[
printHeader,
{ fontSize: 8, alignment: 'right', style: 'tableExample',
table: {
widths: width,
headerRows: 1, body: arr },
layout: 'lightHorizontalLines' }] }
在哪里
var printHeader = [ { text: 'COMPANY NAME',alignment:'center' },
{ text: 'Address 1',alignment:'center' },
{ text: 'Address 2',alignment:'center' },
{ text: 'Additional Details,alignment:'center' },
{ text: 'document title',alignment:'center' }];
和
var arr = [[{"text":"","alignment":"left"},"text":"Date","alignment":"left"},
{"text":"Trans #","alignment":"left"},{"text":"Description","alignment":"left"},
{"text":"Ref #","alignment":"left"},{"text":"Debit","alignment":"left"},
{"text":"Credit","alignment":"left"},{"text":"Amount","alignment":"left"},
{"text":"Balance","alignment":"left"}],[{"text":"ACCOUNT : Merchandise Inventory","alignment":"left","colSpan":8},"","","","","","","",
{"text":"1,646,101.06"}],["","10/13/2015","ST#0094",{"text":"","alignment":"left"},{"text":"","alignment":"left"},"546.94","0.00","546.94","1,646,648.00"],[{"text":"Total","alignment":"left","bold":true},"","","","",
{"text":"546.94","alignment":"right","bold":true},
{"text":"0.00","alignment":"right","bold":true},
{"text":"","alignment":"right","bold":true},
{"text":"546.94","alignment":"right","bold":true}],[{"text":"ACCOUNT : Accounts Payable-Main","alignment":"left","colSpan":8},"","","","","","","",
{"text":"-1,741,953.62"}],["","10/13/2015","ST#0094",
{"text":"","alignment":"left"},
{"text":"","alignment":"left"},"0.00","546.94","-546.94","-1,742,500.56"],
[{"text":"Total","alignment":"left","bold":true},"","","","",
{"text":"0.00","alignment":"right","bold":true},
{"text":"546.94","alignment":"right","bold":true},
{"text":"","alignment":"right","bold":true},
{"text":"-546.94","alignment":"right","bold":true}]
我搜索了 web workers,发现它可以解决这个 UI 卡住问题。所以我尝试为它创建一个网络 worker :
$('#makepdf').click(function(){
var worker = new Worker("<?php echo URL::to('/'); ?>/js/worker.js");
worker.addEventListener('message',function(e){
console.log('Worker said: ',e.data);
},false);
worker.postMessage(docDefinition);
//worker.js
self.addEventListener('message', function(e) {
self.postMessage(e.data);
}, false);
console.log()
的输出:
Worker said: Object {pageOrientation: "portrait", content: Array[7]} its logging correctly the json structure.
到目前为止一切顺利。但是在我将 pdfmake.min.js
和 vfs_font.js
添加到 worker 之后,我得到了错误 Uncaught TypeError: Cannot read property 'createElementNS' of undefined
.
我什至在开始使用 worker 之前就收到了错误。
能否用pdfmake插件实现web worker?
最佳答案
简单的回答
只需提供一个虚拟构造函数:
var document = { 'createElementNS': function(){ return {} } };
var window = this;
importScripts( 'pdfmake.min.js', 'vfs_fonts.js' );
或者,如果您认为它太脏,请导入 XML-JS (仅 60k)并为 pdfmake 创建一个虚拟文档.
importScripts( 'tinyxmlw3cdom.js' );
var window = this;
var document = new DOMDocument( new DOMImplementation() );
importScripts( 'pdfmake.min.js', 'vfs_fonts.js' );
解释
已知 pdfmake 是 incompatible与 worker 。
就其本身而言,pdfmake does not use创建元素NS。然而它的缩小脚本 pdfmake.min.js
做,显然是为了创建一个下载链接。
无论如何我们都不需要下载链接,所以只给它一个虚拟对象让它开心(暂时)。
如果将来它需要一个真正的 DOM,坏消息是文件是unavailable在网络 worker 中。好消息是我们有一个纯 javascript 实现。 Download XML-JS,提取并找到 tinyxmlw3cdom.js
,导入它,您可以创建一个功能文档。
除了文档,自vfs_fonts.js
通过window
变量获取pdfmake,需要引入window作为global的别名。
对我来说,这些步骤使 pdfmake 在 web worker 中工作。
保存文件需要将pdfmake提供的base64数据转换成二进制下载。许多脚本可用,例如 download.js .在下面的代码中,我使用了 FileSaver .
代码
我的 worker 是 Builder可以缓存。如果您在服务器端组成工作人员,你可以摆脱堆栈和构建函数并直接调用pdfmake,使两个 js 代码更加简单。
主要 HTML:
<script src='FileSaver.min.js'></script>
<script>
function base64ToBlob( base64, type ) {
var bytes = atob( base64 ), len = bytes.length;
var buffer = new ArrayBuffer( len ), view = new Uint8Array( buffer );
for ( var i=0 ; i < len ; i++ )
view[i] = bytes.charCodeAt(i) & 0xff;
return new Blob( [ buffer ], { type: type } );
}
//////////////////////////////////////////////////////////
var pdfworker = new Worker( 'worker.js' );
pdfworker.onmessage = function( evt ) {
// open( 'data:application/pdf;base64,' + evt.data.base64 ); // Popup PDF
saveAs( base64ToBlob( evt.data.base64, 'application/pdf' ), 'General Ledger.pdf' );
};
function pdf( action, data ) {
pdfworker.postMessage( { action: action, data: data } );
}
pdf( 'add', 'Hello WebWorker' );
pdf( 'add_table', { headerRows: 1 } );
pdf( 'add', [ 'First', 'Second', 'Third', 'The last one' ] );
pdf( 'add', [ { text: 'Bold value', bold: true }, 'Val 2', 'Val 3', 'Val 4' ] );
pdf( 'close_table' );
pdf( 'add', { text: 'This paragraph will have a bigger font', fontSize: 15 } );
pdf( 'gen_pdf' ); // Triggers onmessage when it is done
// Alternative, one-size-fit-all usage
pdf( 'set', { pageOrientation: 'landscape', footer: { text: 'copyright 2015', fontSize: 8, alignment:'center'}, content:[ "header", { fontSize: 8, alignment: 'right', table: { headerRows: 1, body: [[1,2,3],[4,5,6]] } }] } );
pdf( 'gen_pdf' );
</script>
worker :
//importScripts( 'tinyxmlw3cdom.js' );
//var document = new DOMDocument( new DOMImplementation() );
var document = { 'createElementNS': function(){ return {} } };
var window = this;
importScripts( 'pdfmake.min.js', 'vfs_fonts.js' );
(function() { 'use strict';
var doc, current, context_stack;
function set ( data ) {
doc = data;
if ( ! doc.content ) doc.content = [];
current = doc.content;
context_stack = [ current ];
}
set( {} );
function add ( data ) {
current.push( data );
}
function add_table ( template ) {
if ( ! template ) template = {};
if ( ! template.table ) template = { table: template };
if ( ! template.table.body ) template.table.body = [];
current.push( template ); // Append table
push( template.table.body ); // Switch context to table body
}
function push ( data ) {
context_stack.push( current );
return current = data;
}
function pop () {
if ( context_stack.length <= 1 ) return console.warn( "Cannot close pdf root" );
context_stack.length -= 1;
return current = context_stack[ context_stack.length-1 ];
}
function gen_pdf() {
pdfMake.createPdf( doc ).getBase64( function( base64 ) {
postMessage( { action: 'gen_pdf', base64: base64 } );
} );
}
onmessage = function( evt ) {
var action = evt.data.action, data = evt.data.data;
switch ( action ) {
case 'set': set( data ); break;
case 'add': add( data ); break;
case 'add_table' : add_table( data ); break;
case 'close_table': pop(); break;
case 'gen_pdf': gen_pdf(); break;
}
};
})();
关于javascript - 如何使用 web worker 使用 makepdf 渲染 PDF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32689932/
在我的 OpenGL 程序中,我按顺序执行以下操作: // Drawing filled polyhedrons // Drawing points using GL_POINTS // Displa
我想传递一个包含原始页面的局部变量,这个变量只包含一个带有值的符号。 当我使用此代码时,它运行良好,可以在部分中访问 origin 变量: render :partial => "products",
为什么这个 HTML/脚本(来自“JavaScript Ninja 的 secret ”)不渲染? http://jsfiddle.net/BCL54/
我想在阅读完 View 后返回到特定的网页位置(跳转到页内 anchor )。换句话说,在 views.py 中,我想做类似的事情: context={'form':my_form} return r
我有一个包含单条折线的 PathGeometry,并以固定的间隔向该线添加一个新点(以绘制波形)。使用 Perforator 工具时,我可以看到每次向直线添加一个点时,WPF 都会将整个 PathGe
尝试了解如何消除或最小化网站上不同 JavaScript 库的渲染延迟。 例如,如果我想加载来自许多社交网络的“即时”关注按钮,它们似乎会相互阻止渲染,并且您会收到令人不快的弹出窗口。 (func
我有以 xyz 点格式表示 3D 表面(即地震断层平面)的数据。我想创建这些表面的 3D 表示。我使用 rgl 和 akima 取得了一些成功,但是它无法真正处理可能会自行折叠或在同一 x,y 点具有
我正在用 Libgdx 编写一个小游戏。 我有一个 Render[OpenGL] 线程,它不断对所有对象调用 render() 和一个更新线程不断对所有对象调用 update(double delta
我有一个 .Rmd 文件包含: ```{r, echo=FALSE, message=FALSE, results='asis'} library(xtable) print(xtable(group
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 9 年前。 Improve
请不要评判我,我只是在学习 Swift。 最近我安装了 MetalPetal 框架,并按照说明操作: https://github.com/MetalPetal/MetalPetal#example-
如果您尝试渲染 Canvas 宽度和高度之外的图像,计算机是否仍会尝试渲染它并使用资源来尝试渲染它?我只是想找出在尝试渲染图像之前检查图像是否在 Canvas 内是否更好。 最佳答案 我相信它仍然在无
我在 safari 中渲染时遇到问题。 在 firefox、chrome 和 IE 上。如下图所示: input.searchbox{-webkit-border-radius:10px;-moz-b
我正在尝试通过远程桌面在 Windows7 下运行我在 RHEL7 服务器中制作的 java 程序。 服务器中的所有java程序都无法通过远程桌面呈现。如果我在服务器位置访问服务器本身,它们看起来没问
我正处于一个新项目的设计阶段,该项目将采用数据集并将其加载到文档中,然后围绕模板呈现文档。呈现的文件可以是 CSV 数据集、PDF 营销信函、电子邮件……很多东西。数据不会是数学方程式,我只是在寻找一
有没有办法在不同的 div 下渲染 React 组件的子组件? ... ... ... ... ...
使用以下代码: import numpy as np from plotly.offline import iplot, init_notebook_mode import plotly.graph_
截至最近, meteor 的所有文档都指出 onRendered是一种在模板完成渲染时获取回调的新方法。和 rendered只是为了向后兼容。 但是,这似乎对我不起作用。 onRendered永远不会
所以在我的基本模板中,我有:{% render "EcsCrmBundle:Module:checkClock" %} 然后我创建了 ModuleController.php ... getDoctr
我正在使用 vue-mathjax 来编译我的 vue 项目中的数学方程。它正在编译第一个括号 () 之间的文本。我想防止编译括号内的字符串。在文档中我发现,对于$符号,如果我们想逃避编译,我们需要使
我是一名优秀的程序员,十分优秀!