简体   繁体   English

从 html 生成可点击的 pdf

[英]Generate a clickable pdf from html

In Summary :总结

I want to dynamically generate pdfs from html. I want the resultant pdf to be searchable/clickable - NOT an image.我想从 html 动态生成 pdf。我希望生成的 pdf 可搜索/可点击 - 而不是图像。 I would like a way to do this that is compatible with vue3.我想要一种与 vue3 兼容的方法来做到这一点。

Background :背景

I have a Vue3 project that returns long and wordy lists of results from an API.我有一个 Vue3 项目,它从 API 返回长而冗长的结果列表。

On the site, the results are in accordions and look great.在网站上,结果是手风琴式的,看起来很棒。

I want to let my users download a PDF of the results.我想让我的用户下载一个 PDF 的结果。 I would like to make a minimal template for the pdf that shows an expanded (no accordions) version of the result list.我想为 pdf 制作一个最小模板,显示结果列表的扩展(无手风琴)版本。

As far as I can tell there are two basic ways to do this:据我所知,有两种基本方法可以做到这一点:

  1. Create a print style in css and let users "save" the result to file as a pdf在 css 中创建打印样式,让用户将结果“保存”到文件中,作为 pdf
  2. use one of a number of "html2pdf" style modules to generate the pdf使用多个“html2pdf”样式模块之一生成 pdf

Neither approach seems to really do what I want:这两种方法似乎都没有真正做到我想要的:

routing the user to a print result leads to differing behaviour on mobile and desktop and I can't figure out how to tell the browser to just offer a pdf download.将用户路由到打印结果会导致移动和桌面上的行为不同,我不知道如何告诉浏览器只提供 pdf 下载。

all the various "htmltpdf" type modules I have found so far have great options and defaults but they output the pdf as an image...到目前为止我发现的所有各种“htmltpdf”类型的模块都有很好的选项和默认值,但它们 output pdf 作为图像......

I want my users to be able to select and copy the contents of the pdf - there are phone numbers and links embedded for example.我希望我的用户能够拨打 select 并复制 pdf 的内容 - 例如嵌入了电话号码和链接。

Is there some way to do this in vue;有没有办法在 vue 中做到这一点; A pleasant and nice-looking download experience AND a clickable/searchable pdf?令人愉悦且美观的下载体验以及可点击/可搜索的 pdf?

You can use puppeteer to create pdf using html.您可以使用 puppeteer 使用 html 创建 pdf。

Step 1: Install puppeteer第一步:安装木偶师

npm i puppeteer

Step 2: Write a function to that renders your html into the browser and saves the page as pdf第 2 步:写入 function 以将您的 html 呈现到浏览器中并将页面另存为 pdf

async getPdfFromHtml(html: string): Promise<any> {
  const browser = await puppeteer.launch({ headless: true });
  
  const page = await browser.newPage();
  await page.setContent(html);
  const pdfBuffer = await page.pdf({ printBackground: true, format: 'A4' });
  await page.close();
  await browser.close();

  return pdfBuffer;
}

Step 3: Call this function wherever you want:第 3 步:随时随地拨打此电话 function:

const html = 'your-html-template-string';

// here you will get the pdf buffer
const pdfBuffer = await getPdfFromHtml(html);

Step 4: Now you can send your pdf buffer to frontend.第 4 步:现在您可以将 pdf 缓冲区发送到前端。 The following is an example of how I do in express.js以下是我在 express.js 中的操作示例

const buffer = pdfBuffer.toString('base64').replace(/([^\0]{76})/g, '$1\n') + '\n\n';

res.header('Content-type', 'application/pdf');
res.send(buffer);

Step 5: Now on frontend, all you need is call this api using an achor tag and the pdf will be downloaded.第 5 步:现在在前端,您只需使用 achor 标记调用此 api 即可下载 pdf。

Optional: Another alternative is to upload this buffer to aws-s3 and return the url to FE, the pdf will be downloaded once you redirect to that url.可选:另一种选择是将此缓冲区上传到 aws-s3 并将 url 返回给 FE,一旦您重定向到该 url,将下载 pdf。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM