Welcome to follow my public number
The Code of Life
I have a bold idea that I will write until I die. If I stop writing on that day, I may die. Ha ha.
Hello, everyone. I’m your siege lion, bitch love Ken, a passionate man forever.
Recently, I received an optimization requirement: add the function of printing and generating PDF for the graphic introduction of previous travel documents
Of course, we need to rely on html2Canvas and jspdf.min.js libraries. Html2canvas is used to generate canvas, and jspdf.min.js is used to generate PDF.
First we need to introduce HTML2Canvas, JSPDF
import html2canvas from 'html2canvas'
import './jspdf.min.js'
Copy the code
If there is a scroll bar, place the scroll bar at the top first
document.body.scrollTop = document.documentElement.scrollTop = 0
if(! selector) {
throw new Error('the lack of the selector')
}
let el = document.querySelector(selector)
if(! el) {
throw new Error('Not found' + selector + 'Corresponding DOM node')
}
Copy the code
Set the background color to white, and then after the image is transformed, get the image pixels at the truncation point, scan the pixel color from the truncation point up line, the color of this line is all white, which means that the truncation starts from here, and move everything from this height to the next page
html2canvas(el, {
allowTaint: true.
useCORS: true.
dpi: 120.// Image sharpness problem
background: '#FFFFFF'.// If the specified div has no background color, it defaults to black
}).then(canvas= > {
// Height of HTML page not generated PDF
var leftHeight = canvas.height
var a4Width = 595.28
var a4Height = 841.89 // Size of A4, 210mm x 297mm, each side retains 10mm margin, display area 190x277
// a PDF page displays the canvas height generated by the HTML page;
var a4HeightRef = Math.floor((canvas.width / a4Width) * a4Height)
// PDF page offset
var position = 0
var pageData = canvas.toDataURL('image/jpeg'.1.0)
var pdf = new jsPDF('p'.'pt'.'a4') //A4 paper, longitudinal
var index = 1.
canvas1 = document.createElement('canvas'),
height
pdf.setDisplayMode('fullwidth'.'continuous'.'FullScreen')
var pdfName = title
function createImpl(canvas) {
console.log(leftHeight, a4HeightRef)
if (leftHeight > 0) {
index++
var checkCount = 0
if (leftHeight > a4HeightRef) {
var i = position + a4HeightRef
for (i = position + a4HeightRef; i >= position; i--) {
var isWrite = true
for (var j = 0; j < canvas.width; j++) {
var c = canvas.getContext('2d').getImageData(j, i, 1.1).data
if (c[0] != 0xff || c[1] != 0xff || c[2] != 0xff) {
isWrite = false
break
}
}
if (isWrite) {
checkCount++
if (checkCount >= 10) {
break
}
} else {
checkCount = 0
}
}
height = Math.round(i - position) || Math.min(leftHeight, a4HeightRef)
if (height <= 0) {
height = a4HeightRef
}
} else {
height = leftHeight
}
canvas1.width = canvas.width
canvas1.height = height
console.log(index, 'height:', height, 'pos', position)
var ctx = canvas1.getContext('2d')
ctx.drawImage(
canvas,
0.
position,
canvas.width,
height,
0.
0.
canvas.width,
height,
)
var pageHeight = Math.round((a4Width / canvas.width) * height)
// pdf.setPageSize(null, pageHeight)
if(position ! =0) {
pdf.addPage()
}
pdf.addImage(
canvas1.toDataURL('image/jpeg'.1.0),
'JPEG'.
10.
10.
a4Width,
(a4Width / canvas1.width) * height,
)
leftHeight -= height
position += height
if (leftHeight > 0) {
setTimeout(createImpl, 500, canvas)
} else {
pdf.save(pdfName + '.pdf')
}
}
}
// When the content does not exceed the size of a PDF page, no pagination is required
if (leftHeight < a4HeightRef) {
pdf.addImage(
pageData,
'JPEG'.
0.
0.
a4Width,
(a4Width / canvas.width) * leftHeight,
)
pdf.save(pdfName + '.pdf')
} else {
try {
pdf.deletePage(0)
setTimeout(createImpl, 500, canvas)
} catch (err) {
// console.log(err);
}
}
})
Copy the code
If it is a continuous table, our solution is not to use one table to fill all the data, which is a bit like the page-loading data. If we use multiple tables to loop the data, and set each table to the height of a4 paper, we may be able to avoid truncation