Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/415.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 幻影JS pdf至标准输出_Javascript_Pdf_Stdout_Phantomjs - Fatal编程技术网

Javascript 幻影JS pdf至标准输出

Javascript 幻影JS pdf至标准输出,javascript,pdf,stdout,phantomjs,Javascript,Pdf,Stdout,Phantomjs,我拼命地想把phantomJS生成的PDF输出到stdout-like 我得到的是一个空的PDF文件,虽然它的大小不是0,但它显示一个空白页面 var page = require('webpage').create(), system = require('system'), address; address = system.args[1]; page.paperSize = {format: 'A4'}; page.open(address, function (status) {

我拼命地想把phantomJS生成的PDF输出到stdout-like

我得到的是一个空的PDF文件,虽然它的大小不是0,但它显示一个空白页面

var page = require('webpage').create(),
system = require('system'),
address;

address = system.args[1];
page.paperSize = {format: 'A4'};

page.open(address, function (status) {
    if (status !== 'success') {
        console.log('Unable to load the address!');
        phantom.exit();
    } else {
        window.setTimeout(function () {
            page.render('/dev/stdout', { format: 'pdf' });
            phantom.exit();
        }, 1000);
    }
});
我这样称呼它:
phantomjs rasterize.jshttp://google.com>test.pdf

我尝试将
/dev/stdout
更改为
system.stdout
,但没有成功。将PDF直接写入文件不会有任何问题


我正在寻找一个跨平台的实现,所以我希望这在非linux系统上是可以实现的。

是否必须将pdf输出到标准输出?无法将代码更改为:

var page = require('webpage').create(),
system = require('system'),
address;

address = system.args[1];
output  = system.args[2];
page.paperSize = {format: 'A4'};

page.open(address, function (status) {
    if (status !== 'success') {
        console.log('Unable to load the address!');
        phantom.exit();
    } else {
        window.setTimeout(function () {
            page.render(output, { format: 'pdf' });
            phantom.exit();
        }, 1000);
    }
});
然后像这样使用它:

phantomjs rasterize.js http://google.com test.pdf
    if( fileName == STDOUT_FILENAME ){
#ifdef Q_OS_WIN32
        _setmode(_fileno(stdout), O_BINARY);            
#endif      

        ((File *)system->_stderr())->write(QString::fromAscii(name.constData(), name.size()));

#ifdef Q_OS_WIN32
        _setmode(_fileno(stdout), O_TEXT);
#endif          
    }

在Windows上将输出写入
/dev/stdout/
/dev/stderr/
时,
PhantomJS
将执行以下步骤(如中的
呈现
方法所示):

  • 在缺少
    /dev/stdout/
    /dev/stderr/
    的情况下,会分配一个临时文件路径
  • 使用临时文件路径调用
    renderPdf
  • 将网页呈现到此文件路径
  • 将此文件的内容读入
    QByteArray
  • 在字节数组上调用
    QString::fromscii
    ,并写入
    stdout
    stderr
  • 删除临时文件
  • 首先,我为
    PhantomJS
    构建了源代码,但注释掉了文件删除。在下一次运行中,我能够检查它所呈现的临时文件,结果证明它完全正常。我还尝试运行了
    phantomjs.exe rasterize.jshttp://google.com >test.png
    具有相同的结果。这立即排除了渲染问题,或者任何与PDF相关的问题,这意味着问题必须与数据写入
    stdout
    的方式有关

    到了这个阶段,我怀疑是否有一些文字编码的恶作剧正在进行。从以前的运行中,我得到了同一文件的有效版本和无效版本(本例中为PNG)

    使用一些C#代码,我运行了以下实验:

    //Read the contents of the known good file.
    byte[] bytesFromGoodFile = File.ReadAllBytes("valid_file.png");
    //Read the contents of the known bad file.
    byte[] bytesFromBadFile = File.ReadAllBytes("invalid_file.png");
    
    //Take the bytes from the valid file and convert to a string
    //using the Latin-1 encoding.
    string iso88591String = Encoding.GetEncoding("iso-8859-1").GetString(bytesFromGoodFile);
    //Take the Latin-1 encoded string and retrieve its bytes using the UTF-8 encoding.
    byte[] bytesFromIso88591String = Encoding.UTF8.GetBytes(iso88591String);
    
    //If the bytes from the Latin-1 string are all the same as the ones from the
    //known bad file, we have an encoding problem.
    Debug.Assert(bytesFromBadFile
        .Select((b, i) => b == bytesFromIso88591String[i])
        .All(c => c));
    
    注意,我使用ISO-8859-1编码作为
    QT
    使用它作为。事实证明,所有这些字节都是相同的。这个练习的目的是看看我是否可以模仿导致有效数据无效的编码步骤

    为了进一步的证据,我进行了调查

    • system.cpp
      中,
      system
      类包含对
      stdout
      stdin
      stderr
      对象的引用,这些对象被设置为使用
      UTF-8
      编码
    • 写入
      stdout
      时,调用
      文件
      对象的
      写入
      函数。此函数支持写入文本文件和二进制文件,但由于
      系统
      类初始化它们的方式,所有写入操作都将被视为写入文本文件
    因此,问题归结为:我们需要对标准输出执行二进制写入,但我们的写入最终被视为文本,并对其应用编码,从而导致生成的文件无效


    鉴于上述问题,如果不修改
    PhantomJS
    代码,我看不到任何方法可以在Windows上以您想要的方式工作。因此,它们是:

    第一个更改将提供一个函数,我们可以调用
    文件
    对象来显式执行二进制写入

    \phantomjs\src\filesystem.h
    中添加以下函数原型:

    bool binaryWrite(const QString &data);
    
    并将其定义放入
    \phantomjs\src\filesystem.cpp
    (此方法的代码来自此文件中的
    write
    方法):

    将其更改为:

       if( fileName == STDOUT_FILENAME ){
    #ifdef Q_OS_WIN32
            _setmode(_fileno(stdout), O_BINARY);
            ((File *)system->_stdout())->binaryWrite(QString::fromAscii(ba.constData(), ba.size()));
    #elif            
            ((File *)system->_stderr())->write(QString::fromAscii(name.constData(), name.size()));
    #endif      
    
    #ifdef Q_OS_WIN32
            _setmode(_fileno(stdout), O_TEXT);
    #endif          
        }
    
    因此,代码替换所做的是调用新的
    binaryWrite
    函数,但由
    #ifdef Q_OS_WIN32
    块保护。我这样做是为了保留非Windows系统上的旧功能,这些系统似乎没有出现这个问题(或者它们有吗?)。请注意,此修复程序仅适用于写入
    stdout
    ——如果您愿意,您可以始终将其应用于
    stderr
    ,但在这种情况下,它可能并不重要


    如果您只是想要一个预构建的二进制文件(谁不想要呢?),您可以在my上找到带有这些修复程序的
    phantomjs.exe
    。我的版本大约是19MB,而我之前下载的版本只有6MB,尽管我遵循了说明,所以应该没问题。

    是的,ISO-8859-1是QT的默认编码,因此您需要将所需参数添加到命令行--output encoding=ISO-8859-1,这样pdf输出就不会损坏

    i、 e

    phantomjs.exe rasterize.js——输出编码=ISO-8859-1output.pdf

    而rasterize.js看起来是这样的(经过测试,适用于Unix和Windows)

    或者,您也可以使用标准输出设置编码,如果您正在从UTF-8流读取,那么您可能还必须为标准输出设置编码

    system.stdout.setEncoding('ISO-8859-1');
    system.stdin.setEncoding('UTF-8');
    page.content = system.stdin.read();
    

    什么版本的幻影?尝试升级到最新版本。我在1.9.2 Win8x64上看到了相同的问题。不管道化输出在控制台中似乎有一些pdf内容,但通过phantomjs rasterize.js>test.pdf将输出直接管道化到文件中没有任何作用。@philfreo我在Win7上使用了1.9.2。您能将生成的pdf文件上传到某个地方吗,也许值得研究一下pdf生成的代码是否存在一些视觉问题。这是我正在做的工作,但我的想法是动态创建pdf。在节点webkit push和phantomjs之间来回推送数据。我将深入研究,可能有一些字符正在破坏PDF结构。这太神奇了,非常感谢您的帮助、时间和精力!谢谢你,老兄,这么老的问题怎么会有新的答案,谢谢你的时间!我没有工作
    var page = require('webpage').create(),
    system = require('system');
    
    page.viewportSize = {width: 600, height: 600};
    page.paperSize = {format: 'A4', orientation: system.args[1], margin: '1cm'};
    
    page.content = system.stdin.read();
    
    window.setTimeout(function () {
        try {
            page.render('/dev/stdout', {format: 'pdf'});
        }
        catch (e) {
            console.log(e.message + ';;' + output_file);
        }
        phantom.exit();
    }, 1000);
    
    system.stdout.setEncoding('ISO-8859-1');
    system.stdin.setEncoding('UTF-8');
    page.content = system.stdin.read();