نحوه خودکارسازی اسناد PDF با React و TypeScript

یکی از مشکلی که بسیاری از مشاغل در بعضی از مواقع با آن روبرو خواهند شد ، تولید PDF است – موارد ، گزارش ها ، رسیدها یا فرم ها ، برای ذکر برخی از آنها. از نظر تاریخی ، این دردناک بوده است: Word و Latex برای الگوهای زیادی فراهم نمی کنند ، و گزینه های دیگر راه حل ها یا راه حل های HTML/CSS شکننده هستند یا راه حل هایی مانند WKHTMLTOPDF یا WEASYPRINT که فقط از زیر مجموعه CSS پشتیبانی می کنند.
اما اگر بتوانیم PDF ها را مانند اجزای React درمان کنیم ، چه می شود؟ HTMLDOCS یک کتابخانه جدید است که DX بزرگ وب مدرن را به اسناد ساختمانی می رساند ، مشابه آنچه که ایمیل React برای ایمیل انجام داد.
آنچه می خواهیم بسازیم
در این راهنما ، ما یاد می گیریم:
- یک پروژه React + TypeScript + tailwindcss را تنظیم کنید
- یک الگوی سند فاکتور بسازید
- برای پیش نمایش و ارائه آن به PDF از htmldocs استفاده کنید
- در غرفه های پویا مانند جزئیات مشتری و موارد خط عبور کنید
- به صورت اختیاری الگوی خود را به API منتشر کنید
ابزارهایی که ما استفاده خواهیم کرد
- واکنش و نوع برای اجزای سازنده و نوع ایمنی
- tailwindcss برای یک ظاهر طراحی شده
-
htmldocs
برای ارائه سند
تنظیم پروژه
اگر تازه شروع می کنید ، ساده ترین راه برای داربست یک پروژه جدید است
npx htmldocs@latest init
با این کار یک پروژه آماده برای رفتن با برخی از tepmlates از پیش ساخته شده تنظیم می شود.
برای این آموزش ، فرض خواهیم کرد که قبلاً یک پروژه موجود داریم و می خواهیم اضافه کنیم htmldocs
به آن ابتدا بسته ها را به صورت دستی نصب خواهیم کرد:
npm install htmldocs @htmldocs/react @htmldocs/render
سپس ، شما می خواهید ایجاد کنید documents
پوشه برای الگوهای شما.
mkdir documents
import { Document } from "@htmldocs/react";
import "~/index.css"; // import global TailwindCSS file
function Invoice() {
return (
<Document size="A4" orientation="portrait">
<h1 className="text-xl font-bold">Invoice starterh1>
Document>
)
};
export default Invoice;
در داخل پوشه جدید ، یک فایل جدید به نام ایجاد کنید Invoice.tsx
:
همچنین باید این پوشه را به tsconfig خود اضافه کنید:
// tsconfig.json
{
"include": [..., "documents"],
}
و همچنین tailwind.config.js شما:
/** @type {import('tailwindcss').Config} */
module.exports = {
//... other config options
content: [..., "./documents/**/*.{js,jsx,ts,tsx}"],
};
سرانجام ، شما می خواهید یک اسکریپت جدید به بسته خود اضافه کنید.
// package.json
{
...
"scripts": {
"docs:dev": "npx htmldocs@latest dev"
},
}
حالا ، وقتی دویدید npm run docs:dev
، شما باید یک سرور پیش نمایش زنده را با سند جدید خود مشاهده کنید.
اضافه کردن داده های پویا
در htmldocs ، داده های پویا به عنوان غرفه به مؤلفه منتقل می شوند. بیایید الگوی استارت ما را برای به دست آوردن جزئیات مشتری و همچنین مجموعه ای از خدمات تغییر دهیم. ما همچنین طرح را تازه می کنیم و برخی از محاسبات قیمت را اضافه خواهیم کرد.
import { Document, Head, Page, Footer } from "@htmldocs/react";
import "../src/styles/tailwind.css"; // import global TailwindCSS file
interface Service {
name: string;
description?: string;
quantity: number;
rate: number;
}
interface InvoiceProps {
customerName: string;
customerEmail: string;
services: Service[];
}
function Invoice({ customerName, customerEmail, services }: InvoiceProps) {
const subtotal = services.reduce(
(acc, service) => acc + service.quantity * service.rate,
0
);
const taxRate = 0.1; // 10% tax
const tax = subtotal * taxRate;
const total = subtotal + tax;
return (
<Document size="A4" orientation="portrait">
<Head>
<title>Invoice for {customerName}title>
Head>
<Page className="p-8">
<div className="flex justify-between items-start mb-8">
<div>
<h1 className="text-2xl font-bold my-0">INVOICEh1>
<p className="text-gray-600">{new Date().toLocaleDateString()}p>
div>
<div className="text-right">
<p className="font-medium">{customerName}p>
<p className="text-gray-600">{customerEmail}p>
div>
div>
<table className="w-full mb-8">
<thead>
<tr className="border-b">
<th className="text-left py-2">Serviceth>
<th className="text-right py-2">Qtyth>
<th className="text-right py-2">Rateth>
<th className="text-right py-2">Amountth>
tr>
thead>
<tbody>
{services.map((service, index) => (
<tr key={index} className="border-b">
<td className="py-2">
<div>
<p className="font-medium">{service.name}p>
{service.description && (
<p className="text-sm text-gray-600">{service.description}p>
)}
div>
td>
<td className="text-right py-2">{service.quantity}td>
<td className="text-right py-2">${service.rate.toFixed(2)}td>
<td className="text-right py-2">
${(service.quantity * service.rate).toFixed(2)}
td>
tr>
))}
tbody>
table>
<div className="flex flex-col items-end gap-2">
<div className="flex justify-between w-48">
<span>Subtotal:span>
<span>${subtotal.toFixed(2)}span>
div>
<div className="flex justify-between w-48">
<span>Tax ({(taxRate * 100)}%):span>
<span>${tax.toFixed(2)}span>
div>
<div className="flex justify-between w-48 font-bold border-t pt-2">
<span>Total:span>
<span>${total.toFixed(2)}span>
div>
div>
<Footer
position="bottom-center"
className="text-center text-gray-600"
marginBoxStyles={{
marginBottom: "0.5in",
}}
>
{() => (
<p>Thank you for your business!p>
)}
Footer>
Page>
Document>
);
}
Invoice.PreviewProps = {
customerName: "Acme Corp",
customerEmail: "billing@acmecorp.com",
services: [
{ name: "Web Design", description: "Homepage redesign", quantity: 1, rate: 1500 },
{ name: "Consulting", description: "Technical architecture review", quantity: 2, rate: 800 },
],
};
export default Invoice;
Invoice.PreviewProps
به تنظیم پیش فرض های پیش فرض روی سند برای ارائه کمک می کند. این یک ویژگی مورد نیاز برای اطمینان از اینکه سند شما قادر به تهیه صحیح است.
اکنون سند شما باید به این شکل باشد:
برای ایجاد دستی یک سندی بر اساس این الگوی ، می توانید روی “پر و تولید” کلیک کنید که برای پر کردن جزئیات فرم ایجاد می شود
انتشار به یک API
HTMLDOCS همچنین یک سرویس ابری را ارائه می دهد که می توانید اسناد را منتشر کنید تا آنها را در پشت یک API REST ساده قرار دهید.
قبل از انتشار ، باید یک شناسه سند را به پرونده اضافه کنید:
// rest of Invoice.tsx
Invoice.PreviewProps = {
customerName: "Acme Corp",
customerEmail: "billing@acmecorp.com",
services: [
{ name: "Web Design", description: "Homepage redesign", quantity: 1, rate: 1500 },
{ name: "Consulting", description: "Technical architecture review", quantity: 2, rate: 800 },
],
};
// add this line
Invoice.documentId = "invoice"
export default Invoice;
سپس ، شما می توانید اجرا کنید
npx htmldocs@latest login
npx htmldocs@latest publish documents/Invoice.tsx
سپس ، شما می توانید برای دیدن سند بارگذاری شده وارد داشبورد شوید
اکنون می توانید با برقراری یک تماس API ساده ، یک فایل PDF ایجاد کنید!
curl -X POST https://htmldocs.com/api/documents/invoice \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"props": {
"services": [
{
"name": "Web Design",
"rate": 1500,
"quantity": 1,
"description": "Homepage redesign"
},
{
"name": "Consulting",
"rate": 800,
"quantity": 2,
"description": "Technical architecture review"
}
],
"customerName": "Acme Corp",
"customerEmail": "billing@acmecorp.com"
},
"format": "json"
}'
و آنجا می رویم!
برای کسب اطلاعات بیشتر در مورد HTMLDOCS ، این موارد را بررسی کنید: