【问题标题】:PDFkit js how to save document to file (Win 8 app)PDFkit js如何将文档保存到文件(Win 8应用程序)
【发布时间】:2015-06-21 13:51:53
【问题描述】:

我正在开发一个使用 PDFKit 生成 PDF 的 Windows 8 Javascript 应用程序。

通常您会使用管道创建一个 blobstream,然后创建一个发送到浏览器的 URL。这仅适用于网站从服务器运行的情况,因为它是本地应用程序,所以情况并非如此。但是我确实可以访问文件系统,并且我想将生成的 PDF 保存到文件中。

为此,我受到了这个问题的启发: How to pipe a stream using pdfkit with node js

我使用 Browserify 尝试了上述两种解决方案,将打印机代码替换为保存到文件的代码:

Windows.Storage.ApplicationData.current.localFolder.createFileAsync("test.pdf",
    Windows.Storage.CreationCollisionOption.replaceExisting).then(function (file) {
        //write as text 
        Windows.Storage.FileIO.writeTextAsync(file, data).then(function () {});
        //or write as buffer
        var buffUTF8 = Windows.Security.Cryptography.CryptographicBuffer.convertStringToBinary(data, 0);
        Windows.Storage.FileIO.writeBufferAsync(file, buffUTF8).then(function () {});
    });

如您所见,我都尝试使用写入文本或写入缓冲区,都给了我完全相同的文件。

PDF 文件已创建,但当我打开它时显示一个空白页。如果我在文本编辑器中打开 pdf 并将其与有效的 PDF 进行比较,我可以看出文件的流部分具有不同类型的字符。

此外,Visual Studio 输出窗口向我发送关于 URI 编码无效的 Javascript 运行时错误消息。

所以这显然是一个编码问题,我不确定下一步该怎么做。有关如何将 PDFkit 文档保存到文件的任何提示?

【问题讨论】:

    标签: javascript file windows-8 character-encoding pdfkit


    【解决方案1】:

    我采取了不同的方法,发现 base64 是要走的路。这样,我不仅可以在 Windows 上工作,还可以在 OSX 等其他平台上工作。

    关键是使用 blob-stream.js 和 FileReader 对象将 Blob 对象转换为数据 url(基本上是 base64)。

    <script src="/pdfkit.js"></script>
    <script src="/blob-stream.js"></script>
    

    对于 Windows,然后将 base64 转换为 IBuffer 对象并将其保存到文件中。下面是一个示例,var base64 之后的部分是特定于 Windows 的,但它在其他平台上的工作方式类似:

    var doc = new PDFDocument({ size: 'A4', layout: 'portrait' });
    stream = doc.pipe(blobStream());
    
    stream.on('finish', function () {
        fileReader = new FileReader();
    
        fileReader.onload = function () {
            //get base64 part of the data url
            var base64 = fileReader.result.substr(fileReader.result.indexOf(',') + 1);
            //create file, create IBuffer, save and launch pdf reader
            Windows.Storage.ApplicationData.current.temporaryFolder.createFileAsync("test.pdf", Windows.Storage.CreationCollisionOption.generateUniqueName).then(function (file) {
                var buffUTF8 = Windows.Security.Cryptography.CryptographicBuffer.decodeFromBase64String(base64);
                Windows.Storage.FileIO.writeBufferAsync(file, buffUTF8).then(function () {
                    Windows.System.Launcher.launchFileAsync(file);
                });
            });
        };
        fileReader.onerror = function () {
            console.log('error loading file');
        };
    
        fileReader.readAsDataURL(stream.toBlob('application/pdf'));
    });
    
    //draw PDF content here
    doc.text('Hello World!', 100, 100);
    doc.end();
    

    【讨论】:

    • Windows.Security.Cryptography.CryptographicBuffer.decodeFromBase64String(base64) 帮助我成为 IE Mobile atob() 替代品。
    【解决方案2】:

    这在 Firefox 中对我有用

    _downloadAsPdf: (data) =>
    
    doc = new PDFDocument()
    imgData = @renderer.canvas.toDataURL('image/png')
    stream = doc.pipe(blobStream())
    doc.image(imgData)
    doc.end()
    
    stream.on 'finish', ->
    
      blob = stream.toBlob('application/pdf')
    
      # save as file
      date = new Date()
      time = date.toLocaleTimeString()
      pageNum = data.pageNumber
      fileName = "page" + pageNum + "_" + time + ".pdf"
      saveAs(blob, fileName)
    

    【讨论】:

      【解决方案3】:

      适合我的跨浏览器解决方案:将您从 PDF 生成的数据 URL 设置为临时链接元素的来源:

      function data_url_to_download(data_url, filename) {
        var a = document.createElement("a");
        document.body.appendChild(a);
        a.style = "display: none;";
        a.href = data_url;
        a.download = filename;
        a.click();
        a.remove();
      };
      

      PDF 生成完成后可以自动下载文件:

      // Generate document to a stream with PDFKit, then...
      stream.on("finish", function() {
          data_url_to_download(stream.toBlobURL("application/pdf"), "output.pdf");
      });
      

      【讨论】:

        猜你喜欢
        • 2014-06-13
        • 1970-01-01
        • 1970-01-01
        • 2013-04-18
        • 2013-03-01
        • 1970-01-01
        • 2014-09-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多