日韩欧美国产精品免费一二-日韩欧美国产精品亚洲二区-日韩欧美国产精品专区-日韩欧美国产另-日韩欧美国产免费看-日韩欧美国产免费看清风阁

LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開(kāi)發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

在 React 中生成并導(dǎo)出 PDF 文件

admin
2024年10月25日 14:20 本文熱度 941

PDF 為世界提供了一種在各種設(shè)備之間高度兼容的共享文檔和媒體的通用格式,但以編程方式生成它們通常很棘手。
我們將探索如何在不同環(huán)境中使用 JavaScript 生成 PDF 的一些選項(xiàng)。

生成 PDF 的麻煩之處……

在使用 PDF 時(shí),您通常會(huì)像閱讀圖像一樣閱讀或查看它們,但如果您曾經(jīng)嘗試復(fù)制某些文本、搜索 PDF 或單擊鏈接,您可能已經(jīng)注意到 PDF 不僅僅是一張靜態(tài)圖像。
許多生成 PDF 的解決方案依賴于將其生成為圖像,但缺乏嵌入文本所提供的可訪問(wèn)性和可用性。
但根據(jù)您的限制和環(huán)境,也許值得權(quán)衡。

html2pdf.js

html2pdf.js是一個(gè)客戶端庫(kù),允許您使用 Canvas(特別是html2canvas和jsPDF)從 HTML 呈現(xiàn) PDF 。
要?jiǎng)?chuàng)建 PDF,您需要指定要從頁(yè)面呈現(xiàn)的元素,將其傳遞到 html2pdf 實(shí)例中,然后庫(kù)將生成 PDF 并提示用戶下載它。

如何開(kāi)始?

您可以通過(guò)幾種不同的方式包含 html2pdf.js,包括指向第三方 CDN 的腳本標(biāo)簽或通過(guò) npm 導(dǎo)入它。
如果使用 npm,首先安裝 html2pdf.js:

npm install html2pdf.js

將其作為依賴項(xiàng)導(dǎo)入:

import html2pdf from 'html2pdf.js';

選擇一個(gè) HTML 元素并將其傳遞給 html2pdf:

html2pdf(document.getElementById('my-id'));

這將提示您的用戶開(kāi)始下載文件。
您還可以在支持的地方動(dòng)態(tài)導(dǎo)入依賴項(xiàng),以避免將其直接與您的應(yīng)用程序捆綁在一起并僅在需要時(shí)加載它。

const html2pdf = await require('html2pdf.js');
html2pdf(document.getElementById('my-id'));

文檔中有很多可用的選項(xiàng)。
例如,在我顯示發(fā)票的頁(yè)面上,html2pdf.js 將呈現(xiàn):

它有什么好處?

html2pdf 允許您使用 JavaScript 直接在瀏覽器中生成 PDF。這意味著您無(wú)需向外部服務(wù)器發(fā)出請(qǐng)求,因此您需要處理的基礎(chǔ)設(shè)施和網(wǎng)絡(luò)請(qǐng)求更少。
您還可以使用任何工具以任何您想要的方式管理您的 HTML,因?yàn)樽罱K您將傳遞一個(gè) DOM 節(jié)點(diǎn)來(lái)呈現(xiàn)。
這也提高了您已經(jīng)構(gòu)建的頁(yè)面的可重用性,因此您不必為 UI 和 PDF 版本分別維護(hù)多個(gè)頁(yè)面。

還有什么更好的呢?

總體來(lái)說(shuō),它運(yùn)行良好,但在生成目標(biāo) HTML 時(shí),渲染可能會(huì)有點(diǎn)不一致。CSS 可能不太完美,有時(shí)頁(yè)面的某些部分可能會(huì)出現(xiàn)偏移或被切斷。
雖然 API 為您提供了一些選項(xiàng)和靈活性,但您仍然受到頁(yè)面呈現(xiàn)方式的限制。您可以隱藏內(nèi)容 ( data-html2canvas-ignore),但您無(wú)法提供特定樣式,例如,您可以像打印預(yù)覽那樣提供特定樣式。
頁(yè)面移動(dòng)導(dǎo)致項(xiàng)目被切斷的問(wèn)題似乎可以通過(guò)在 html2pdf.js GitHub Issues中找到的一些基本樣式來(lái)修復(fù)。

@layer base { img { display: initial; } }

PDF Kit 和 React PDF

PDF Kit是另一個(gè) JavaScript HTML 到 PDF 渲染工具,其工作方式略有不同。
PDF Kit 本身實(shí)際上并不呈現(xiàn) HTML,但允許您使用它所描述的類似 HTML5 Canvas 的 API 來(lái)創(chuàng)建和定位元素。
但是在 React 環(huán)境中工作,你會(huì)得到更接近 HTML 或 JSX 的東西,其中React PDF使用組件 API 和 PDF Kit 來(lái)提供一種更自然的方式來(lái)表達(dá)內(nèi)容(就像在 React 中一樣)。
在這里我們將重點(diǎn)介紹 React PDF,但如果您想要純 JavaScript 版本,請(qǐng)查看文檔。

如何開(kāi)始?

首先使用 npm 安裝 React PDF:

npm install @react-pdf/renderer

導(dǎo)入一些組件作為依賴項(xiàng):

import { renderToStream, Page, Text, Document, StyleSheet } from '@react-pdf/renderer';

設(shè)置一些樣式:

const styles = StyleSheet.create({
  page: { 
    padding: 50
  },
  title: {
    fontSize22,
  },
});

創(chuàng)建文檔組件:

const MyDocument = () => (
  <Document>
    <Page style={styles.page}>
      <Text style={styles.title}>My Text</Text>
    </Page>
  </Document>

);

如果渲染到流,請(qǐng)使用該renderToStream方法:

await renderToStream(<MyDocument />)

此時(shí)它就像一個(gè) React 組件,因此您可以設(shè)置動(dòng)態(tài)值以便更輕松地處理動(dòng)態(tài)數(shù)據(jù)。

創(chuàng)建動(dòng)態(tài)路由器處理程序

使用它的一個(gè)示例是創(chuàng)建一個(gè) Next.js 路由處理程序,它像頁(yè)面一樣查詢數(shù)據(jù)并呈現(xiàn) PDF,并將其作為流返回。
為此,您可以在 創(chuàng)建路線app/pdf/route.tsx,在其中,您將創(chuàng)建 PDF 組件、渲染它,并在 Next.js 響應(yīng)中返回它。
例如:

import { NextResponse } from 'next/server';

const Invoice = (props: InvoiceProps) => (
  <Document>{/** PDF Components */}</Document>
);

export async function GET(request: Request, { params }: { params: { invoiceId: string; }}) {
  const invoice = await getMyInvoice(params.invoiceId);
  const stream = await renderToStream(<Invoice {...invoice} /
>)
  return new NextResponse(stream as unknown as ReadableStream)
}

這可能導(dǎo)致:

它有什么好處?

渲染效果非常好。
您可以選擇如何呈現(xiàn)文檔,包括在視圖中呈現(xiàn)它以及將其呈現(xiàn)到 ReadableStream 中。
如果您想要?jiǎng)?chuàng)建一個(gè)可動(dòng)態(tài)生成和傳送 PDF 的路由器處理程序,或者想要在服務(wù)器上生成 PDF,那么這會(huì)非常方便,就像上面的例子一樣。
它還允許您嵌入實(shí)際字體。打開(kāi) PDF 后,文本節(jié)點(diǎn)實(shí)際上是可選擇和可復(fù)制的,這出于多種原因非常有用。

還有什么更好的呢?

目前,React PDF 似乎無(wú)法在即將推出的 React 19 中使用。GitHub Issues 中有一些關(guān)于如何支持(甚至是分叉)的討論。
雖然您能夠以類似 HTML/JSX 的結(jié)構(gòu)創(chuàng)建 PDF,但您仍然必須使用其組件單獨(dú)維護(hù)它,但如果不使用像 html2pdf 這樣的直接從 DOM 中抓取它的解決方案,該語(yǔ)法可能比其他一些 API 更好。

Puppeteer

Puppeteer 是一種流行的選項(xiàng),用于處理 HTML、截屏以及嘗試渲染通常涉及瀏覽器的動(dòng)態(tài)內(nèi)容。
這是我們可以用來(lái)根據(jù)現(xiàn)有內(nèi)容創(chuàng)建 PDF 的另一個(gè)工具。
其工作方式是 Puppeteer 幫助自動(dòng)化 Chromium 瀏覽器,一旦連接,我們就可以導(dǎo)航到不同的頁(yè)面,與這些頁(yè)面進(jìn)行交互,并且可以想象,截取屏幕截圖甚至生成 PDF。

如何開(kāi)始?

使用 Puppeteer 非常依賴于您所處的環(huán)境。例如,在無(wú)服務(wù)器函數(shù)中運(yùn)行 Puppeteer 很棘手,但幸運(yùn)的是我有一個(gè)教程:使用 Puppeteer 和 Next.js API 路由構(gòu)建 Web Scraper。
對(duì)于這個(gè)例子,我假設(shè)您能夠運(yùn)行標(biāo)準(zhǔn) Puppeteer 庫(kù)。
首先,安裝 Puppeteer:

npm install puppeteer

將模塊導(dǎo)入到您的項(xiàng)目中:

import puppeteer from 'puppeteer';

然后我們可以自動(dòng)運(yùn)行 Puppeteer,例如,如果我們想要生成 PDF,我們可以運(yùn)行:

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://spacejelly.dev');
const pdf = await page.pdf();
await browser.close();

此時(shí),Uint8Array我們可以將 PDF 上傳到我們選擇的位置。
例如:
?
提示:查看我的YouTube 視頻,我將在其中向您展示如何使用 Clerk 創(chuàng)建經(jīng)過(guò)身份驗(yàn)證的 Puppeteer 會(huì)話以生成 PDF!
或者,您也可以截取屏幕截圖,而不是生成 PDF:

const screenshot = await page.screenshot();

不同之處在于.screenshot生成圖像而不是 PDF 文件,這是一個(gè)重要的區(qū)別。
Alt:使用 Puppeteer 生成的 PDF

它有什么好處?

Puppeteer 用途非常廣泛。你可以通過(guò)多種方式來(lái)控制頁(yè)面并與之交互。
設(shè)置好頁(yè)面后,您可以使用.pdf包含嵌入文本的方法輕松捕獲它,這對(duì)于高質(zhì)量 PDF 至關(guān)重要。

還有什么更好的呢?

對(duì)于這種用例來(lái)說(shuō),Puppeteer 可能比較慢,但其他方法速度更快,可以帶來(lái)更好的用戶體驗(yàn)。
在環(huán)境中進(jìn)行設(shè)置也可能很棘手,假設(shè)您有一個(gè)可以設(shè)置 Puppeteer 的環(huán)境。

我們最好的選擇是什么?

它們都有各自的優(yōu)點(diǎn)和缺點(diǎn),但我認(rèn)為 React PDF 是我們更好的解決方案。
當(dāng)然,我們必須創(chuàng)建和維護(hù)一個(gè)單獨(dú)的模板,但該模板不需要與 UI 完全相同,對(duì)于交互性有不同的標(biāo)準(zhǔn)和期望級(jí)別。
與 html2pdf 相比,React PDF 為我們提供了嵌入文本。
與 Puppeteer 相比,React PDF 速度更快,設(shè)置也更容易。


該文章在 2024/10/28 16:27:22 編輯過(guò)
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國(guó)內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場(chǎng)、車(chē)隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場(chǎng)作業(yè)而開(kāi)發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉(cāng)儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷(xiāo)售管理,采購(gòu)管理,倉(cāng)儲(chǔ)管理,倉(cāng)庫(kù)管理,保質(zhì)期管理,貨位管理,庫(kù)位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

主站蜘蛛池模板: 91探花国产综合在线精品 | 中文字幕亚洲欧美在线不卡 | 日韩电影免费观看2025 | 男女直接做无 | 欧美.成人.综合在线 | 国产小视频在 | 国产综合成人一区二区三区电影院 | 国产精品日日做人人爱 | 亚洲欧美日韩国产精选在线观看 | 一区二区三区高清视频 | 日本夜爽爽一区二区三区 | 91精品国产亚洲爽啪在线观看 | 午夜a成v人电影 | 在线播放国产一区 | 五月婷婷深爱 | 亚洲日韩欧美不卡 | аⅴ资源中文在线天堂 | 国产精品jizz在线观看直播 | 小黄文污到你湿 | 亚洲一线二线三线免费视频 | yellow高清免费观看日本 | 国产日本欧美在线一区二区 | 国产亚洲理论在线观看 | 五月综合激情婷婷六月 | 国产伦精品一区二区三区在 | 欧美特黄一级大黄录像 | 国产日韩a视频在线播放视频 | 亚洲色偷偷偷鲁综合 | 亚洲精品视频在线播放 | 把你的香肠放入我的扇贝里 | 91青青青青国产在线观看 | 国产精品边叫边喷水 | 亚洲熟女综合 | 勃起又长又黑又粗毛又多 | 99精品国产福利免费一区二区 | 国产思思99re99 | 亚洲人午夜射精 | 91国在线啪精品一区 | 欧美国产亚洲一区 | 亚洲不卡一卡2 | 亚洲欧美日韩ⅴ在线观看91 |