PhantomJS:导出PDF到标准输出
有没有一种方法可以在不指定扩展名为.PDF的输出文件的情况下触发PhantomJS中的PDF导出功能?我们想使用标准输出输出PDF。很抱歉回答太长;我有一种感觉,在我的一生中,我需要参考这个方法几十次,所以我会写“一个答案来统治所有人”。我将首先对文件、文件描述符、(命名的)管道和输出重定向进行一些讨论,然后回答您的问题PhantomJS:导出PDF到标准输出,pdf,pipe,file-descriptor,phantomjs,io-redirection,Pdf,Pipe,File Descriptor,Phantomjs,Io Redirection,有没有一种方法可以在不指定扩展名为.PDF的输出文件的情况下触发PhantomJS中的PDF导出功能?我们想使用标准输出输出PDF。很抱歉回答太长;我有一种感觉,在我的一生中,我需要参考这个方法几十次,所以我会写“一个答案来统治所有人”。我将首先对文件、文件描述符、(命名的)管道和输出重定向进行一些讨论,然后回答您的问题 考虑一下这个简单的C99程序: #包括 #包括 int main(int argc,char*argv[]) { 如果(argc一些文件。我们要求程序写入其标准输出(而不是常
考虑一下这个简单的C99程序:
#包括
#包括
int main(int argc,char*argv[])
{
如果(argc<2){
printf(“用法:%s文件名\n”,argv[0]);
返回1;
}
FILE*FILE=fopen(argv[1],“w”);
如果(!文件){
printf(“没有这样的文件:%s\n”,argv[1]);
返回2;
}
fprintf(文件,“一些文本…”);
fclose(文件);
返回0;
}
非常简单。它接受一个参数(文件名)并在其中打印一些文本。再简单不过了
用
clangwrite_to_file.c-o write_to_file.o
或gcc write_to_file.c-o write_to_file.o
编译它
现在,运行/write_to_file.o some_file
(它将打印到some_file
)。然后运行cat some_file
。正如预期的那样,结果是一些文本…
现在让我们来想象一下。在终端中键入(./write_to_file.o/dev/stdout)>一些文件。我们要求程序写入其标准输出(而不是常规文件),然后将stdout
重定向到some_文件
(使用>some_文件
)。我们本可以使用以下任何一项来实现这一点:
(/write_to_file.o/dev/stdout)>一些文件
,意思是“使用stdout
”
(/write_to_file.o/dev/stderr)2>一些文件
,意思是“使用stderr
,并使用2>重定向它。”
(/write_to_file.o/dev/fd/2)2>一些文件
,与上面相同stderr
是默认情况下分配给Unix进程的第三个文件描述符(在stdin
和stdout
之后)
(/write_to_file.o/dev/fd/5)5>一些文件
,意思是“使用第六个文件描述符,并将其重定向到一些文件
”
如果不清楚,我们使用的是Unix管道而不是实际的文件(毕竟在Unix中,所有东西都是文件)。我们可以用这个管道做各种各样的奇妙的事情:将它写入一个文件,或者将它写入一个命名的管道,并在不同的进程之间共享它
现在,让我们创建一个命名管道:
mkfifo my_pipe
如果现在键入ls-l
,您将看到:
total 32
prw-r--r-- 1 pooriaazimi staff 0 Jul 15 09:12 my_pipe
-rw-r--r-- 1 pooriaazimi staff 336 Jul 15 08:29 write_to_file.c
-rwxr-xr-x 1 pooriaazimi staff 8832 Jul 15 08:34 write_to_file.o
注意第二行开头的p。这意味着my_pipe
是一个(命名)管道
现在,让我们指定要对管道执行的操作:
gzip -c < my_pipe > out.gz &
或
你会得到
[1]+ Done gzip -c < my_pipe > out.gz
我们已经成功地gzip
ed了我们的文本
执行gzip-d out.gz
解压此gzip
ed文件。它将被删除,并将创建一个新文件(out
)<代码>禁止进入
获取我们:
some text...
这正是我们所期望的
不要忘记用rm my_pipe
移除管道
现在回到幻影
这是一个简单的PhantomJS脚本(render.coffee
,用CoffeeScript编写),它包含两个参数:URL和文件名。它加载URL、呈现URL并将其写入给定的文件名:
system=需要“系统”
renderUrlToFile=(url、文件、回调)->
page=require('webpage')。create()
page.viewportSize={宽度:1024,高度:800}
page.settings.userAgent='Phantom.js bot'
page.open url,(状态)->
如果状态不是“成功”
console.log“无法呈现“#{url}”
其他的
page.render文件
删除页面
回调url,文件
url=system.args[1]
文件名=system.args[2]
console.log“将呈现到#{file_name}”
renderUrlToFile“http://{url}”,文件名,(url,文件)->
console.log“将“#{url}”呈现为“#{file}”
幻影。退出()
现在,在终端中键入phantomjs render.coffee news.ycombinator.com hn.png
,将黑客新闻首页呈现为文件hn.png
。它按预期工作。phantomjs render.coffee news.ycombinator.com hn.pdf
也是如此
让我们重复一下我们之前用C程序所做的:
(phantomjs render.coffee news.ycombinator.com /dev/fd/5) 5> hn.pdf
它不起作用了…:(为什么?因为,如上所述:
渲染(文件名)
将网页呈现到图像缓冲区并保存
作为指定的文件
当前,输出格式是根据文件自动设置的
支持的格式有PNG、JPEG和PDF
它失败了,仅仅是因为/dev/fd/2
和/dev/stdout
都不是以.PNG
结尾,等等
但不用担心,命名管道可以帮助你
创建另一个命名管道,但这次使用扩展名.pdf
:
mkfifo my_pipe.pdf
cat < my_pipe.pdf > hn.pdf &
现在,让它简单地cat
它的inout tohn.pdf
:
mkfifo my_pipe.pdf
cat < my_pipe.pdf > hn.pdf &
看看美丽的hn.pdf
显然,您想做一些更复杂的事情,只需cat
ing输出,但我相信现在您应该做的事情已经很清楚了:)
TL;医生:
cat < my_pipe.pdf > hn.pdf
我不知道它是否能解决您的问题,但您也可以检查添加到PhantomJS 1.6中的新
renderBase64()
方法:
不幸的是,该功能尚未在wiki上记录://正如Niko所指出的,您可以使用
renderBase64()
将网页渲染到图像缓冲区,并将结果作为base64编码字符串返回。但目前这只适用于PNG、JP
phantomjs render.coffee news.ycombinator.com my_pipe.pdf
mkfifo my_pipe.pdf
cat < my_pipe.pdf > hn.pdf
rm my_pipe.pdf
var base64image = page.renderBase64('PNG');
var fs = require("fs");
fs.write("/dev/stdout", base64image, "w");
page.render(output);
var fs = require("fs");
var pdf = fs.read(output);
fs.write("/dev/stdout", pdf, "w");
fs.remove(output);