我正在使用react-typescript,并且我已经在此参考的帮助下从html页面成功创建了一个PDF文件 Generating a PDF file from React Components
但是如果我们想创建一个包含多个页面的PDF,那该怎么办? 使用a4尺寸的页面,在所有边和每个新页面都有适当的边距,应该应用边距。
这是我的代码。
private printDocument() {
const input = document.getElementById("pdf");
html2canvas(input)
.then((canvas) => {
const pdf = new jsPDF("p", "px", "a4");
pdf.addHTML(input, 0, 0, {
pagesplit: true,
background: "#ffffff",
}, () => {
pdf.save("download.pdf");
});
});
}
请帮助我的银色。 提前谢谢
答案 0 :(得分:1)
我尝试使用jsPDF来解决这个问题,但我没有成功。 jsPDF管理要分页的内容的方式对我来说并不清楚。 所以我决定使用另一个惊人的js库pdfMake。 我在这个问题中得到了这些信息:Generating PDF files with JavaScript
在你提到的问题(Generating a PDF file from React Components)中,最好的答案是一个处理分页的好方法。你为每个页面制作一个div。但在我的情况下,我的内容可以在空间上增加你的垂直尺寸,所以我无法修复div的垂直尺寸。 所以,我确实喜欢这个:
printDocument() {
const divs = document.getElementsByClassName('example');
const newList = [].slice.call(inputs);
var contentArray = []
var docDefinition = {
pageSize: {width: 800, height: 1173},
content: [
{
text: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Confectum ponit legam, perferendis nomine miserum, animi. Moveat nesciunt triari naturam.'
}
]
}
Promise.map(newList, async (element, index) => {
let canvas = await html2canvas(element);
const imgData = await canvas.toDataURL('image/png');
// console.log("imgData URL => ", imgData)
// margin horizontal -40 = removing white spaces
return contentArray[`${index}`] = [{ image: imgData, width: canvas.width, height: canvas.height, margin: [-40, 0] }, {
text: ` ${index} - Lorem ipsum dolor sit amet, consectetur adipisicing elit. Confectum ponit legam, perferendis nomine miserum, animi.`
}];
}).then(
() => ( docDefinition.content.push(contentArray))
).then(
() => {
console.log("... starting download ...")
pdfMake.createPdf(docDefinition).download('examplePdf.pdf')
}
)
}
// In your react's component constructor ...
constructor(props) {
super(props);
this.printDocument = this.printDocument.bind(this)
}
// the imports below ...
import Promise from 'bluebird';
import html2canvas from 'html2canvas';
import pdfMake from 'pdfmake/build/pdfmake.js';
import pdfFonts from "pdfmake/build/vfs_fonts.js";
pdfMake.vfs = pdfFonts.pdfMake.vfs;
// i'm using these middlewares
import promise from 'redux-promise'
import multi from 'redux-multi'
import thunk from 'redux-thunk'
<div>
The approach here is: a div it's not a page. Because if the image generated by the canvas element it's bigger than the page vertical size, we'll need to control the pagination by ourselves. So, we broke our content in small elements to the pdf generator handle the pagination to us. This way we garantee that the pagination will occurs without cuts.
<div className="example" style={{ backgroundColor: '#ffffff', maxWidth: '800px', maxHeight: '1173px', borderStyle: 'groove', borderColor: 'red', margin: '0px' }} >
// any content or component here, we need maxHeight to be sure that the div's height size it's not bigger than the your PDF doc's height dimension, else your div may never be rendered inside it.
</div>
<div className="example" style={{ backgroundColor: '#ffffff', maxWidth: '800px', maxHeight: '1173px', borderStyle: 'groove', borderColor: 'red', margin: '0px' }} >
// any content or component here, we need maxHeight to be sure that the div's height size it's not bigger than the your PDF doc's height dimension, else your div may never be rendered inside it.
</div>
<div className="example" style={{ backgroundColor: '#ffffff', maxWidth: '800px', maxHeight: '1173px', borderStyle: 'groove', borderColor: 'red', margin: '0px' }} >
// any content or component here, we need maxHeight to be sure that the div's height size it's not bigger than the your PDF doc's height dimension, else your div may never be rendered inside it.
</div>
</div>
<div>
<button onClick={this.printDocument}> print using PDFMake </button>
</div>
使用bluebird的Promise.map
和async / await资源,我们可以确保我们等到画布生成所有图像的结束。此过程可能需要一段时间,具体取决于图像的大小。
http://bluebirdjs.com/docs/api/promise.map.html
看看pdfMake的github: https://github.com/bpampuch/pdfmake
他的游乐场有很好的例子和如何: http://pdfmake.org/playground.html
我仍然会尝试用这种方式升级以解决这个问题,但这是我解决问题的最快方式,我希望对某些人有用。
答案 1 :(得分:0)
你尝试了吗?
const printDocument= () => {
const input = document.getElementById('divToPrint');
const input2 = document.getElementById('divToPrint2');
const pdf = new jsPDF();
html2canvas(input)
.then((canvas) => {
const imgData = canvas.toDataURL('image/png');
pdf.addImage(imgData, 'JPEG', 0, 0);
pdf.addPage();
html2canvas(input2)
.then((canvas2) => {
const imgData2 = canvas2.toDataURL('image/png');
pdf.addImage(imgData2, 'JPEG', 0, 0);
pdf.save("download.pdf");
})
;
})
;
}