gpt4 book ai didi

reactjs - 使用 html2canvas 和 jspdf 在 React 中从 Html 生成 pdf

转载 作者:行者123 更新时间:2023-12-03 14:18:18 25 4
gpt4 key购买 nike

我已经在 React 中成功从 html2canvas 和 jspdf 生成了 pdf。但问题是 pdf 中渲染的图像被拉伸(stretch)。请让我知道做此类工作的最佳选择是什么。是否有可能在不使用 html2canvas 的情况下将 HTML 直接渲染为 pdf?下面是我的截图 Output Screenshotpdf's screenshot

下面是我的代码

import React, { Component } from 'react';
import * as jsPDF from 'jspdf';
import * as html2canvas from 'html2canvas';


class Invoice extends Component {

handlePdf = () => {
const input = document.getElementById('page');

html2canvas(input)
.then((canvas) => {
const imgData = canvas.toDataURL('image/png');
const pdf = new jsPDF('p', 'px', 'a4');
var width = pdf.internal.pageSize.getWidth();
var height = pdf.internal.pageSize.getHeight();

pdf.addImage(imgData, 'JPEG', 0, 0, width, height);
pdf.save("test.pdf");
});
};

render() {

const hrStyle = {
border: '5px solid rgb(23, 162, 184)'
};

const subtotal = [0, ...this.props.inputs.totals];
const add = (a, b) => a + b;
const sum = subtotal.reduce(add);

const tax = sum * 0.1;
const total = sum + tax;

return (
<React.Fragment>
<div className="col-12 col-lg-6" id="page">
<div className="container-fluid bg-info text-white">
<div className="row">
<div className="col text-left m-2">
<p>Your Company Name</p>
<h2>Invoice</h2>
</div>
<div className="col text-right">
<p>22 Yusen St</p><br />
<p>borburn</p><br />
<p>WSN</p>
</div>
</div>
</div>
<div className="container-fluid">
<div className="row">
<div className="col-4">
<h5>Billed To</h5>
<p>{this.props.inputs.company}</p>
<p>{this.props.inputs.address}</p>
<p>{this.props.inputs.zip}</p>
</div>
<div className="col-4">
<div>
<h5>Invoive number</h5>
<p>Za{Math.floor((Math.random() * 100) + 1)}</p>
</div>
<div>
<h5>Date</h5>
<p>{this.props.inputs.date}</p>
</div>
</div>
<div className="col-4">
<div>
<h5>Invoice Totals</h5>
<p>${total}</p>
</div>
</div>
</div>
</div>
<hr style={hrStyle} />
<div className="Invoices">
<table className="table">
<thead>
<tr>
<th>Description</th>
<th>Unit Price</th>
<th>Quantity</th>
<th>Total</th>
</tr>
</thead>
<tbody>
{this.props.inputs.invoices.map((invoice, index) => {
return (
<tr key={index}>
<td>{invoice.description}</td>
<td>{invoice.unit}</td>
<td>{invoice.quantity}</td>
<td>{invoice.quantity * invoice.unit}</td>
</tr>
)
})
}
</tbody>
</table>
</div>
<hr />
<div className="col-12 text-right" >
<h5 className="m-2">
Subtotal<span className="m-2">${sum}</span>
</h5 >
<p>Tax(10%)<span className="m-2">${tax.toFixed(2)}</span></p>
<h2>Total<span className="m-2">${total}</span></h2>
</div>
</div>
<button onClick={this.handlePdf} className="btn btn-primary btn-lg mx-auto">Generate PDF</button>

</React.Fragment >
);
}
}

export default Invoice;

最佳答案

您可以使用优秀的React-pdf图书馆。它具有良好的性能,并且还有一个额外的好处:如果您打印文本,它将是可搜索的。

如果您需要在 DOM 和 PDF 中渲染页面,我建议您自己创建 primitives并使用它们代替 dom 标签(div、p 等)。通过使用这些原语,您将能够在 dom 和 pdf 中渲染相同的组件。

这是一个 View 原语的示例:

import React from 'react';
import { View as ViewPDF } from '@react-pdf/renderer';
import { RENDERING_CONTEXT, withRenderingContext } from '../RenderingContext';

class View extends React.Component {
render() {
const { renderingContext, children, className, style } = this.props;
const isPdf = renderingContext === RENDERING_CONTEXT.PDF;
return isPdf
? <ViewPDF className={className} style={style}>
{children}
</ViewPDF>
: <div className={className} style {style}>
{children}
</div>;
}
}
export default withRenderingContext(View);

RenderingContext 是 context您可以在其中存储当前渲染上下文。然后,您只需使用设置正确上下文的提供程序来包装您的 pdf 页面。将根据渲染上下文使用正确的组件(来自react-pdf或dom)。

在您的示例中,您可以简单地用这些原语替换 Invoice 中的 dom 元素。然后,您就可以在 pdf 文件或 dom 中渲染 Invoice 组件。

关于reactjs - 使用 html2canvas 和 jspdf 在 React 中从 Html 生成 pdf,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53117630/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com