使用html2canvas和jsPDF做前端页面的pdf导出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ExportPdf</title>
</head>
<style>
    #detail{<!-- -->
        width: 50%;
        height: 1000px;
        background-color: aqua;
        margin: auto;
    }
    li{<!-- -->
        list-style: none;
        margin-top: 20px;
    }
    label{<!-- -->
        width: 100px;
        display: inline-block;
        text-align: right;
    }
    h3{<!-- -->
        text-align: center;
    }
    form{<!-- -->
        width: 80%;
        margin: auto;
        text-align: center;
    }
    button{<!-- -->
        width: 80px;
        height:30px;
        margin: auto;
        display: block;
        margin-top: 20px;
    }
</style>

<body>
    <div id="detail">
        <h3>exportPdf</h3>
        <form action="">
            <li>
                <label for="userName">Name:</label>
                <input type="text" placeholder="Please Input Your Name" name="userName">
            </li>
            <li>
                <label for="password">Password:</label>
                <input type="text" placeholder="Please Input Your Password" name="password">
            </li>
        </form>
        <button onclick="exportBacisDetailPDF()">Export</button>
    </div>

</body>
<script src="./plug/jspdf.js"></script>
<script src="./plug/html2canvas.js"></script>
<script>
    exportBacisDetailPDF = () => {<!-- -->
        const detail = document.getElementById('detail');
        const imgHeight = detail.clientHeight;
        const imgWidth = detail.clientWidth;
        const scale = 3;
        html2canvas(detail, {<!-- -->
            letterRendering: true,
            allowTaint: true,
            taintTest: false,
            height: imgHeight,
            //  为了使横向滚动条的内容全部展示,这里必须指定
            width: imgWidth,
            backgroundColor: '#fff',
            scale: scale, // 提升画面质量,但是会增加文件大小,
            onclone: (detail) => {<!-- -->
                const inputs = detail.getElementsByTagName("input")
                let inputList = Array.prototype.slice.call(inputs);
                inputList.map((item) => {<!-- -->
                    if (item.placeholder) {<!-- -->
                        item.removeAttribute("placeholder")
                    }
                })//去除input的placeholder
                // onclone logic to resize div
                return new Promise((resolve, reject) => {<!-- -->
                    setTimeout(() => {<!-- -->
                        resolve()
                    }, 500)
                })
            }
        }).then((canvas) => {<!-- -->
            const pageData = canvas.toDataURL('image/jpeg', 1);
            // 设置pdf的尺寸,pdf要使用pt单位 已知 1pt/1px = 0.75   pt = (px/scale)* 0.75
            // scale为上面的scale 缩放了scale倍, 60为pdf四周留白
            let pdfX = (imgWidth + 60) / scale * 0.75
            let pdfY = (imgHeight + 60) / scale * 0.75
            let imgX = (imgWidth / scale )* 0.75
            let imgY = (imgHeight / scale )* 0.75; //内容图片这里不需要留白的距离
            console.log(pdfX,pdfY,imgX,imgY)
            // pdfX,pdfY为pdf的大小,imgX,imgY为内容图片的大小
            let PDF = new jsPDF('', 'pt', [pdfX, pdfY])
            // 7.5 为坐标,让img在pdf中水平垂直居中,四周留白均匀
            PDF.addImage(pageData, 'JPEG', 7.5, 7.5, imgX, imgY);
            //获取当前时间戳
            let timestmp = new Date().getTime()
            PDF.save(`form${<!-- -->timestmp}.pdf`);
        }).catch(() => {<!-- -->
        });
    };
</script>

</html>