PDFkit js如何将文档保存到文件(Win 8应用程序)

PDFkit js how to save document to file (Win 8 app)

本文关键字:Win 应用程序 存到文件 js 文档 PDFkit      更新时间:2023-09-26

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

通常情况下,你会使用管道制作一个blobstream,然后制作一个URL发送到浏览器。只有当网站在服务器上运行时,这才有效,但事实并非如此,因为它是一个本地应用程序。然而,我确实可以访问文件系统,我想将生成的PDF保存到一个文件中。

为了做到这一点,我受到了这个问题的启发:如何使用带有节点js 的pdfkit管道传输流

我使用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进行比较,我可以判断文件的流部分有不同类型的字符。

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

所以这显然是一个编码问题,我不知道下一步该怎么办。关于如何将PDFkit文档保存到文件中,有什么提示吗?

我采取了一种不同的方法,发现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();

这在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)

一个适用于我的跨浏览器解决方案:将您从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");
});