我不久前已经这样做了。我使用了 Handlebars 和 html2pdf。使用 Handlebars,您可以在 HTML 文件中设置数据。它允许您使用 If 语句和 HTML 文件中的每个语句。
首先,我用这样的把手创建了 HTML...
<html>
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous" />
<style>
@page {
@bottom-right {
content: counter(page) " of " counter(pages);
}
}
.hr-golden {
border-color: #d7b436;
height: 1px;
color: #d7b436;
background-color: #d7b436;
}
.hr-black {
margin-top: 0rem;
margin-bottom: 0rem;
border-color: black;
height: 1px;
color: black;
background-color: black;
}
.left-side span {
font-size: 14px;
}
.right-side span {
margin-left: 20px;
font-size: 14px;
}
.tdl {
text-align: left;
font-size: 14px;
}
.tdr {
text-align: right;
font-size: 14px;
}
.golden {
background-color: #d7b436;
}
.golden2 {
background-color: #E5DDC0;
}
.golden-color {
color: #d7b436;
}
.footer {
width: 100%;
height: 100px;
display: flex;
flex-flow: row;
justify-content: space-between;
font-family: Arial Narrow, sans-serif;
}
.price {
display: flex;
max-width: 50%;
min-width: 50%;
height: 5vh;
font-size: 50px;
justify-content: space-between;
}
p {
font-size: 10px;
}
.priceTag {
font-size: 15px;
}
</style>
</head>
<body>
<div id="report" class="container">
<div class="row">
<div class="col-sm-auto col-md-12 text-right">
<img src="../Loggo.png" height="auto" width="200px" style="margin-bottom: 30px;" />
</div>
</div>
<hr class="hr-golden" />
<div class="row">
<div class="col-md-6 text-left left-side">
<span>{{leftSideText1}}</span> <br />
<span>{{leftSideText2}}</span> <br />
<span>{{leftSideText3}}</span> <br />
<span>{{leftSideText4}}</span>
</div>
<div class="col-md-1"></div>
<div class="col-md-5 text-right right-side">
<table style="width: 70%; margin-left: 30%;">
<tr>
<td class="tdl" style="font-size: 16px;">BESTELL-NR.</td>
<td class="tdr" style="font-size: 16px;">{{rightSideText1}}</td>
</tr>
<tr>
<td class="tdl">DATUM</td>
<td class="tdr">{{rightSideText2}}</td>
</tr>
<tr>
<td class="tdl">KUNDEN-NR.</td>
<td class="tdr">{{rightSideText3}}</td>
</tr>
</table>
</div>
</div>
<div class="row" style="margin-top: 50px;">
<div class="col-sm-auto col-md-12 text-center">
<table class="table table-sm" style="width: 100%; border: none;">
<thead style="max-height: 14px;">
<th class="text-left">PRODUKT</th>
<th class="text-center">EINHEIT</th>
<th class="text-center">ANZAHL</th>
<th class="text-right">PREIS</th>
<th class="text-right">GESAMT</th>
</thead>
<tbody>
{{#each data.lists}}
{{#each this.orderers}}
{{#each this.products}}
<tr style="max-height: 14px">
<td class="text-left" style="font-size: 14px;">{{this.product.parent.name}}</td>
<td class="text-center" style="font-size: 14px;">{{this.product.weight}} kg</td>
<td class="text-center" style="font-size: 14px;">{{this.amount}}</td>
<td class="text-right">
<div
style="display: flex; padding-left: 35%; justify-content: space-between; align-items: center;">
<p class="priceTag" style="margin: 0">
€
</p>
<p class="priceTag" style="margin: 0">
{{this.product.price}}
</p>
</div>
</td>
<td class="text-right">
<div
style="display: flex; padding-left: 35%; justify-content: space-between; align-items: center;">
<p class="priceTag" style="margin: 0">
€
</p>
<p class="priceTag" style="margin: 0">
{{this.total}}
</p>
</div>
</td>
</tr>
{{/each}}
{{#if_eq this.name 'initiator'}}
{{else}}
<tr class="golden" style="max-height: 14px; font-size: 14px; align-items: center;">
<td colspan="3" class="text-left" style="padding-bottom: 8px;">{{this.name}}</td>
<td class="text-right" style="font-size: 14px;">SUMME</td>
<td class="text-right" style=" border-top: black 1px solid;">
<div
style="display: flex; padding-left: 35%; justify-content: space-between; align-items: center;">
<p class="priceTag" style="margin: 0">€ </p>
<p class="priceTag" style="margin: 0">
{{this.total}}
</p>
</div>
</td>
</tr>
{{/if_eq}}
{{/each}}
<tr class="golden2" style="border-bottom: black 2px solid; padding-bottom: 20px;">
<td colspan="3" class="text-left" style="padding-bottom: 8px;">{{this.name}}</td>
<td class="text-right">SUMME</td>
<td class="text-right">
<div
style="display: flex; padding-left: 35%; justify-content: space-between; align-items: center;">
<p class="priceTag" style="margin: 0">
€
</p>
<p class="priceTag" style="margin: 0">
{{this.total}}
</p>
</div>
</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
</div>
<div class="row" style="margin-top: 20px;">
<div class="col-md-6 text-left">
<span>GESAMTSUMME INKL. STEUER</span>
</div>
<div class="col-md-6 text-right">
<span>€ {{sumField5}}</span>
</div>
</div>
<hr class="hr-black" />
<div class="row">
<div class="col-md-6 text-left">
<span>GESAMTMENGE</span>
</div>
<div class="col-md-6 text-right">
<span>{{sumField3}} KG</span>
</div>
</div>
<hr class="hr-golden" />
<div class="footer">
<div class="footer-box-1">
<p>
{{footerHeader}}
<br>
<span class="golden-color">
{{footerSection11}}
</span>
<br>
{{footerSection12}}
</p>
</div>
<div class="footer-box-2">
<p>
<br>
{{footerSection21}}<br>
{{footerSection22}}
</p>
</div>
<div class="footer-box-3">
<p>
<br>
{{footerSection31}}<br>
{{footerSection32}}
</p>
</div>
<div class="footer-box-4">
<p>
<br>
{{footerSection41}}<br>
{{footerSection42}}
</p>
</div>
<div class="footer-box-5">
<p>
<span class="golden-color">
<br>
{{footerSection51}}
</span>
<br>
{{footerSection52}}
</p>
</div>
</div>
</div>
</body>
</html>
然后我在我的 React-App 中创建了一个函数。单击下载按钮时调用此函数。
这个函数看起来像这样:
const ExportOrder = async e => {
await $.get('../../templates/report.html', async html => {
const template = await Handlebars.compile(html);
const htmlString = await template({
logoUrl: `https://media.macphun.com/img/uploads/customer/how-to/579/15531840725c93b5489d84e9.43781620.jpg`,
leftSideText1: `${order.customer.firstName} ${order.customer.lastName}`,
leftSideText2: `${order.shipping.address1}`,
leftSideText3: `${order.shipping.postcode} ${order.shipping.city}`,
leftSideText4: `${order.shipping.country}`,
rightSideText1: `${order.orderNumber}`,
rightSideText2: `${order.date ? dateFormat(order.date, 'yyyy-mm-dd') : dateFormat(Date(), 'yyyy-mm-dd')}`,
rightSideText3: `${order.customer.customerId}`,
data: data2, //get from DB or JSON or wherever you want
footerHeader: `asdfsadf`,
footerSection11: `Gasdfasdf`,
footerSection12: `Basdf`,
footerSection21: `Wasdf`,
footerSection22: `IBAN: asdfasdf`,
footerSection31: `T +asdfasdf`,
footerSection32: `BIC: Sasdfasdf`,
footerSection41: `INFOsdfasdf`,
footerSection42: `asdfasdf`,
footerSection51: `tesdf`,
footerSection52: `Text`,
sumField3: amountSum,
sumField5: data2.total.toLocaleString('DE-DE', { maximumFractionDigits: 2, minimumFractionDigits: 2 })
});
const opt = {
margin: 0.5,
filename: `bestellung.pdf`,
image: { type: 'jpeg', quality: 0.98 },
html2canvas: { scale: 2 },
jsPDF: { unit: 'in', format: 'letter', orientation: 'portrait' },
dpi: 300,
letterRendering: true,
useCORS: true,
pagebreak: { mode: ['avoid-all', 'css', 'legacy'] }
};
html2pdf().set(opt).from(htmlString)
}, 'text');
}
函数中的第一行是使用您首先创建的 jQuery 获取 HTML。然后它会用数据填充 HTML,你会得到一个 htmlstring。 html2pdf 在最后一行使用给定的选项生成 pdf。