首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >(JavaScript/Typescript)将多个HTML字符串转换为多个PDF文档并由.zip保存

(JavaScript/Typescript)将多个HTML字符串转换为多个PDF文档并由.zip保存
EN

Stack Overflow用户
提问于 2022-07-27 19:04:39
回答 2查看 147关注 0票数 0

我试图找出将多个HTML字符串转换为PDF(客户端)的最佳方法,将这些字符串添加到.zip文件(最好使用JSZip),然后下载该.zip文件。

这里有一些代码试图实现这一点..。

代码语言:javascript
复制
// HTML examples to render
var tableHtml = `<table>
    <tr>
      <th>Company</th>
      <th>Country</th>
    </tr>
    <tr>
      <td>Alfreds Futterkiste</td>
      <td>Germany</td>
    </tr>
    <tr>
      <td>Centro comercial Moctezuma</td>
      <td>Mexico</td>
    </tr>
  </table>`
var boldHtml = "<p> Hello <strong>World</strong> </p>"
var imageHtml = `<h1> City </h1>
    <img src="https://images.unsplash.com/photo-1582010905429-bef463482aa2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80">`

var htmlToConvert = [tableHtml, boldHtml, imageHtml];

// Convert (using jsPDF, but totally open to other options... As this doesn't work)
let fileNumber = 1;
for (const html of htmlToConvert) {
      let jsPdf = new jsPDF();
      jsPdf.html(html); // This right here seems to be what I can't get working...

      zip.file(`file${fileNumber}.pdf`, jsPdf.output('blob'), { binary: false });

      fileNumber++;
}

// Save .zip file
const blob = await zip.generateAsync({ type: 'blob' });
const fileSaver = await import('file-saver');
fileSaver.default.saveAs(
      blob,
      `example.zip`
);

这段代码不起作用,我认为具体而言,是行jsPdf.html(html)不起作用。一旦.zip下载,有3个PDF文件,但它们都是空白,没有内容。

如果我将jsPdf.html(html)替换为jsPdf.text(html, 1, 1),这似乎是可行的,但它只是简单的html,所以不会呈现任何内容。我确实看了一下这个SO post,并相应地降低了评级,但没有运气。

代码语言:javascript
复制
    "html2canvas": "1.0.0-alpha.12",
    "image-conversion": "^2.1.1",

jsPdf.html有一个回调选项,所以我也尝试了以下代码:

代码语言:javascript
复制
pdf.html(document.body, {
        callback: function (pdf) {
          zip.file(`file${fileNumber}.pdf`, pdf.output('blob'), { binary: false });
        }
});

但是,这里的问题是,在zip文件保存之后可能才会触发回调,因此.zip将是空的。不知道在这种情况下如何使用回调?我可能只是漏掉了一些显而易见的东西。

我愿意使用jsPdf以外的其他工具来完成这个任务,有什么想法吗?

谢谢!:)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-08-01 16:25:11

问题是,在保存zip文件之前,需要等待所有转换完成。您可以通过将回调包装在一个承诺中来实现这一点,以便使用现有的await

代码语言:javascript
复制
await Promise.all(htmlToConvert.map((html, fileNumber) => {
    const jsPdf = new jsPDF();
    return new Promise<void>((resolve, reject) => {
        jsPdf.html(html, {
            callback: function (pdf) {
              zip.file(`file${fileNumber}.pdf`, jsPdf.output("blob"), { binary: false });
              resolve(); // maybe reject if jsPdf is able to signal some kind of error condition?
            },
          });
    })
}));
票数 1
EN

Stack Overflow用户

发布于 2022-07-29 04:02:20

在注释中,我建议这可能不是与zip函数一起使用的方法,因为所有的PDF内容都是通过html传输到客户端设备,以便在它们的cpu和本地资源中生成。事实上,我惊讶地看到文件3中的外部图像没有被CORS策略阻止。

在一次运行中生成3个文件触发来自浏览器请求允许多个下载的响应,因此这个多生成文件并不理想,因为第一次下载之后的下载需要从下载对话框中重新选择。

然而,直接回答你的核心问题

doc.html({html}); // This right here seems to be what I can't get working...

这是一份工作草稿。

代码语言:javascript
复制
<!DOCTYPE html>
    <html lang=en>
      <head>
        <title>Title of the document</title>
<style>
</style>
      </head>
      <body>
<script src="https://code.jquery.com/jquery-2.1.3.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.debug.js" integrity="sha384-NaWTHo/8YCBYJ59830LTz/P4aQZK1sS0SneOgAvhsIl3zBu8r9RevNg5lHCHAuQ/" crossorigin="anonymous"></script>
<script src="https://html2canvas.hertzen.com/dist/html2canvas.js"></script>

<script>
 //

// HTML examples to render BEWARE sub canvas .css defaults mess with scales thus styles/widths may not be as expected the common div wrapper value ${html} below may need tweaking
var Html1 = '<table><tr><th>Company</th>&nbsp;<th>Country</th></tr><tr><td>Alfreds Futterkiste</td>&nbsp;<td>Germany</td></tr><tr><td>Centro comercial Moctezuma</td>&nbsp;<td>Mexico</td></tr></table>'
var Html2 = '<p>Hello<strong> World</strong></p>'
var Html3 = `<h1> City </h1><img src="https://images.unsplash.com/photo-1582010905429-bef463482aa2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=460&q=80">`
var htmlToConvert = [Html1, Html2, Html3];

// Convert (using jsPDF, but totally open to other options... As this doesn't work)
// set counter to 0
let fileNumber = 0;
for (const html of htmlToConvert) {
 fileNumber++;
   var doc = new jsPDF({
      orientation: 'p',

// unit MUST be pt for .html inclusion
      unit: 'pt',

      format: 'a4'
    })

// remember these values are printers point sizes not mm or pixels
    doc.setFontSize(10);

// optional heading text, x(pt), y(pt), var, var, 'alignment' NOTE variable fileNumber set above works for the heading
    doc.text(`File ${fileNumber}`, 298,  10, null, null, 'center');

// doc.html({html}); // This right here seems to be what I can't get working...

// Convert HTML to PDF in JavaScript ensure the file names are different
let name = `File${fileNumber}`
    doc.html(`<div style=width:1350px>${html}</div>`, {
        callback: function(doc) {
                  
                   doc.save(`${name}.pdf`);
        },
        x: 10,
        y: 10
    });
}
</script></body></html>

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73143368

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档