我需要通过流将html转换为pdf,因为将html保存到文件中,然后再次读取并发送到wkhtmltopdf会占用所有可用内存。
以下是我认为使用wkhtmltopdf:可以实现的方法
Node stream > java application wrapping wkhtmltopdf > Node stream
因此,在我的应用程序中,我会从数据源读取数据,将数据管道传输到java应用程序,该应用程序将数据转换为pdf,然后管道传输到响应流。
目前,我正在做一些简单的测试,看看它是如何工作的。我的问题是将数据从节点管道传输到java应用程序,然后将其返回到响应流。
两种代码都很简单:
节点(是的,这是coffeescript):
http = require 'http'
child = require('child_process').spawn 'java', ['PdfStream'], stdout: ['pipe', 'pipe', process.stderr]
server = http.createServer().listen 8000
server.on 'request', (req, res) ->
res.writeHead 200, 'Content-Type': 'application/pdf'
req.pipe(child.stdout, end: false).pipe res, end: true
Java:
public class PdfStream {
public static void main(String[] args) throws IOException {
String[] command = {"wkhtmltopdf", "-", "-"};
ProcessBuilder builder = new ProcessBuilder(command);
Process process = builder.start();
BufferedWriter pdfOut = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
try {
String line;
while ((line = in.readLine()) != null) {
pdfOut.write(line);
pdfOut.flush();
}
} catch (IOException e) {
// exception? what exception?
} finally {
if (pdfOut != null) {
pdfOut.close();
}
if (in != null) {
in.close();
}
}
}
}
但是当我向节点服务器发出POST请求时,它什么都没有出来
cat file.html | java PdfStream
,它有效。此外,如果我更改传递给ProcessBuilder的输出流,如
String[] command = {"wkhtmltopdf", "-", "test.pdf"};
一切都很好。
你能说出这个代码出了什么问题吗?
我突然想到:使用java包装器执行程序有什么意义?我可以直接从节点完成。然后,我阅读了wkhtmltopdf文档,在寻找将流传递到其中的正确方法时,我偶然发现了一个名为wkhtmltox的好灵魂的npm包(https://www.npmjs.com/package/wkhtmltox)它确实做到了这一点。我尝试的方法再简单不过了:
server = http.createServer().listen 8000
server.on 'request', (req, res) ->
res.writeHead 200, 'Content-Type': 'application/pdf'
converter.pdf(req).pipe(res).on('finish', -> console.log 'finished')
而且,它的作用正如承诺的那样。