preface
Recently because of the requirement of front-end PDF generation, this research for a while, found that JSPDF is slightly better, in order to export PDF I have tried several methods, the following to share with you
Either way, the image must be base64 or it won’t display
Method 1: HTML2Canvas + jsPDF generate PDF
This method is to convert HTML content to canvas, then generate image, add image to JSPDF, save export PDF
- Advantages: The generated PDF has good clarity and supports Chinese fonts
- Disadvantages: The generated PDF content size is not controllable depending on the template style, and the HTML template must be displayed,
display:none
orvisibility:hidden
And even set the location,top:-1000%
, also not, will print out a blank below the post code
// HTML generates Canvas images and adds them to PDFdownloadPDF() {// Check whether all images have been converted to base64, if there is no further waiting // I switch to base64 in the onload of all images in the template, call the download method each time, // check whether the download method is consistent with the total number of images to be generatedlet imgload = this.judgeimg()
if(! imgload) {return false
}
const pdf = new window.jsPDF(' '.'pt'.'a4')
let pdfList = document.getElementsByClassName('pdfItem')
for (let i = 0, len = pdfList.length; i < len; i++) {
let target = pdfList[i]
target.style.background = '#FFFFFF'Html2canvas (target, {dpi: 144, // Set dpi to render some onrendered:function(canvas) {const contentWidth = canvas. Width const contentHeight = canvas. Const pageHeight = (contentWidth / 595.28) * 841.89 // HTML pageHeight not generated PDFletLeftHeight = contentHeight // Page offsetletPosition = 0 // Size of a4 paper [595.28,841.89], ImgWidth = 595.28 const imgHeight = (592.28 / contentWidth) * contentHeight const pageData = canvas.toDataURL('image/jpeg', 1.0)
if (leftHeight < pageHeight) {
pdf.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight) // Add a blank page for the next dataif (i < len - 1) {
pdf.addPage()
}
} else {
while (leftHeight > 0) {
pdf.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight) leftHeight -= pageHeight position -= 841.89 // Avoid adding blank pagesif (leftHeight > 0) {
pdf.addPage()
}
}
}
if (i === len - 1) {
pdf.save('the PDF file. PDF'}}})}}Copy the code
Method 2: jsPDF addHTML generates PDF
JsPDF has a direct method to provide HTML to generate PDF, but also to generate HTML screenshots to generate pictures
- Advantages: Simple code, and support Chinese fonts
- Disadvantages: The same HTML template must be displayed,
display:none
orvisibility:hidden
And even set the location,top:-1000%
, also no, will print blank (or all black); The definition is average, not very high, the requirement is not high can use this method
The template page style must be set to BACKGROUND :# FFFFFF; Otherwise the printed background will default to black
The code is posted below
// HTML directly generates PDF screenshotsdownloadPDF () {
let imgload = this.judgeimg()
if(! imgload) {return false
}
const pdf = new window.jsPDF(' '.'pt'.'a4')
let orderList = document.getElementsByClassName('pdfOrder')
for (let i = 0, len = orderList.length; i < len; i++) {
let target = orderList[i]
target.style.background = '#FFFFFF'// Target. Style. width = target'55%'
pdf.addHTML(target, function () {
if (i < len - 1) {
pdf.addPage()
}
if (i === len - 1) {
pdf.save('the PDF file. PDF')}})}}Copy the code
Method three: jsPDF handwriting content generation PDF
Write typesetting line by line according to THE JSPDF API
- Advantages: The generated PDF is high-definition, does not need HTML template, does not need to display in the browser, can be silently exported
- Disadvantages: the default font does not support Chinese font, their typesetting is more troublesome
How to support Chinese fonts?
Since the third method is written out, it certainly can solve the problem of unsupported Chinese fonts. I checked the official website of JSPDF, but could not find the API document. But I found some articles and started my own test.
First, support to set the Chinese font version, so far found methods, Only version 1.4.0 < script SRC = “https://cdn.bootcss.com/jspdf/1.4.0/jspdf.debug.js” > < / script > then download on the net a set of Chinese fonts, it is good to the vera.ttf format. Thanks for the demo of generating font code
// the addFileToVFS method adds the font file doc.addFileToVFS(fileName, Base64content); // Add the font doc.addFont(fileName, fontName, fontStyle); // Use the font doc.setfont (fontName)Copy the code
There is a pit here, I set the font style at that time, and then garbled, indicating that the font style support is not very friendly, but the font size is ok
<button @click="download2PDF" >Export PDF</button>
Copy the code
// Write the PDF by handdownload2PDF () {
this.pdfloading = trueConst PDF = new window.jspdf () // Add and set font pdf.addfont ('Chinese Imitation of song Dynasty. TTF'.'custom'.'normal');
pdf.setFont('custom');
console.log(this.pdfData.length)
for (let i = 0, len = this.pdfData.length; i < len; i++) {
const item = this.pdfData[i]
try {
const promises = [item.imgurl1, item.imgurl2].map(imgurl => {
return imgGetAction(imgurl)
})
Promise.all(promises).then(values => {
console.log(values)
item.pFrontImg = 'data:image/jpeg; base64,'+ btoa(String.fromCharCode(... new Uint8Array(values[0]))) item.pBackImg ='data:image/jpeg; base64,'+ btoa(String.fromCharCode(... new Uint8Array(values[1]))) this.getPdfTemplate(pdf, item)if (i < len - 1) {
pdf.addPage()
}
if (i === len - 1) {
pdf.save('the PDF file. PDF')
this.pdfloading = false
}
})
} catch (error) {
console.log(error)
this.$message.error('PDF export failed ')
this.pdfloading = false
return false}}, // PDF template information getPdfTemplate (PDF, data) {let linePos = 14
pdf.text(60, linePos, 'Order Number' + data.id)
pdf.setFontType('normal'SetFontSize (10.5) linePos += 8 //// Info PDF. Text (15, linePos,'information')
linePos += 5
pdf.text(15, linePos, 'Name:' + data.name)
pdf.text(75, linePos, 'Application Date:'+ data. ApplyDate) PDF. The text (135.5, linePos,'Review Date:'+ data.auditDate) linePos += 5'Front photo:')
pdf.text(75, linePos, 'Reverse photo:')
linePos += 3
pdf.addImage(pFrontImg, 'JPEG', 15, linePos, 50, 60)
pdf.addImage(pBackImg, 'JPEG', 75, linePos, 50, 60)
//// 收取信息 215
linePos += 6
pdf.text(15, linePos, 'Receive information'LinePos += 5 PDF. Text (15, linePos,'Collection Method:' + this.wayName[data.receiveWayId])
pdf.text(75, linePos, Name of Recipient:+ data. DestName) PDF. The text (135.5, linePos,'Receiver's Contact Information:'DestPhone) // Line 225 linePos += 5let addrStr = (data.destProvince + data.destCity + data.destDistrict + data.destAddress) || The '-'
pdf.text(15, linePos, 'Shipping Address:'+ addrStr) //// end footer 230 PDF. Text (15, 240,'Print time:' + formatDate(new Date().valueOf(), 'yyyy-MM-dd hh:mm:ss')) PDF. The text (135.5, 240,Signature of Agent:)}Copy the code
Refer to the content
- JsPDF -CustomFonts-support, add custom font support to jsPDF
- jsPDF-CustomFonts-support (github)