html元素生成pdf 支持自动切割分页

// 导出页面为PDF格式
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
// require('../../static/font/simhei-normal')
export default {
    install(Vue, options) {
        Vue.prototype.getPdf = function (elem) {
            document.body.scrollTop = document.documentElement.scrollTop = 0
            let title = this.htmlTitle
            html2Canvas(document.querySelector(elem), {
                // allowTaint: true,
                useCORS: true,
                logging: true,
            }).then(function (canvas) {
                    //未生成pdf的html页面高度
                    let leftHeight = canvas.height;
                    let a4Width = 190
                    let a4Height = 277   //A4大小,210mm x 297mm,四边各保留10mm的边距,显示区域190x277
                    //一页pdf显示html页面生成的canvas高度;
                    let a4HeightRef = Math.floor(canvas.width / a4Width * a4Height);
                    console.log(a4HeightRef,'a4HeightRef')
                    //pdf页面偏移
                    var position = 0;
                    let pageData = canvas.toDataURL('image/jpeg', 1.0);
                    console.log(pageData, 'pageData')
                    let PDF = new JsPDF('P', 'mm', 'a4'),
                        canvas1 = document.createElement('canvas'),
                        height;
                    PDF.setDisplayMode('fullwidth', 'continuous', 'FullScreen');
                    // PDF.setFont('simhei')
                    PDF.index = 1
                    PDF.index1 = 1
                    function createImpl(canvas) {
                        // PDF.index1++
                        console.log(leftHeight,a4Height,'33333')
                        console.log(PDF.index1++, '3232323232')
                        if (leftHeight > 0) {
                            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);
                                console.log(height,'height234')
                                if (height <= 0) {
                                    height = a4HeightRef;
                                }
                            } else {
                                height = leftHeight;
                            }

                            canvas1.width = canvas.width;
                            canvas1.height = height;

                            console.log( canvas1.height,' canvas1.height')
                            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);
                            if(pageHeight < 277){
                                console.log(1111,'1111')
                                pageHeight = 277
                            }
                            console.log(pageHeight,'pageHeight')
                            if (position != 0) {
                                PDF.addPage();
                            }
                            PDF.addImage(canvas1.toDataURL('image/jpeg', 1.0), 'JPEG', 10, 10, a4Width, a4Width / canvas1.width * height);
                            console.log( PDF.addImage(canvas1.toDataURL('image/jpeg', 1.0), 'JPEG', 10, 10, a4Width, a4Width / canvas1.width * height))
                            leftHeight -= height;
                            position += height;
                            if (leftHeight > 0) {
                                console.log( canvas1.height,' 老王')
                                PDF.setFontSize(12)
                                // PDF.setFont('simhei')
                                // PDF.text('第' + PDF.index + '页' + ' ' + '共'  + '页', 100, 280,); //print number bottom right
                                // PDF.text( PDF.index , 100, 290,); //print number bottom right
                                PDF.index++
                                setTimeout(createImpl, 500, canvas);
                            } else {
                                console.log(canvas1.height,' 老李')
                                PDF.setFontSize(12)
                                // PDF.setFont('simhei')
                                // PDF.text(PDF.index , 100, 290,); //print number bottom right
                                // PDF.text('第' + PDF.index + '页' + ' ' + '共' + PDF.index + '页', 100, 280,); //print number bottom right
                                PDF.index++
                                PDF.save(title + '.pdf')
                            }
                        }
                    }
                    // console.log(PDF.index1++,'252525')
                    //当内容未超过pdf一页显示的范围,无需分页
                    if (leftHeight < a4HeightRef) {
                        // console.log(pageHeight,PDF.setPageSize,'222222')
                        PDF.addImage(pageData, 'JPEG', 0, 0, a4Width, a4Width / canvas.width * leftHeight);
                        PDF.save(title + '.pdf')
                    } else {
                        try {
                            PDF.deletePage(0);
                            setTimeout(createImpl, 500, canvas);
                        } catch (err) {
                            // console.log(err);
                        }
                    }
                }
            )
        }
    }
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在 React 中生成 PDF 并且自动分页,可以使用第三方库 React-PDF。该库提供了一个 `<Document>` 组件和 `<Page>` 组件,其中 `<Page>` 组件可以自动分页。 要生成表格,可以使用 `<Table>` 组件。以下是一个示例代码: ```jsx import React from 'react'; import { Document, Page, Text, View, StyleSheet, Font, Table, TableRow, TableCell } from '@react-pdf/renderer'; // 定义字体 Font.register({ family: 'Noto Sans', src: 'https://fonts.gstatic.com/s/notosans/v12/o-0IIpQlx3QUlC5A4PNb4j5Ba_2iuOw.ttf', }); const styles = StyleSheet.create({ page: { padding: 20, fontFamily: 'Noto Sans', }, section: { marginBottom: 10, }, table: { width: '100%', borderStyle: 'solid', borderWidth: 1, borderColor: '#000', borderLeftWidth: 0, borderTopWidth: 0, }, tableRow: { flexDirection: 'row', }, tableCell: { width: '33.33%', borderStyle: 'solid', borderWidth: 1, borderColor: '#000', borderRightWidth: 0, borderBottomWidth: 0, }, }); const MyDocument = () => { return ( <Document> <Page style={styles.page}> <View style={styles.section}> <Text>这是第一页</Text> </View> <View style={styles.section}> <Table style={styles.table}> <TableRow style={styles.tableRow}> <TableCell style={styles.tableCell}> <Text>列1</Text> </TableCell> <TableCell style={styles.tableCell}> <Text>列2</Text> </TableCell> <TableCell style={styles.tableCell}> <Text>列3</Text> </TableCell> </TableRow> {/* 生成多行 */} {Array.from(Array(20).keys()).map((index) => ( <TableRow style={styles.tableRow} key={index}> <TableCell style={styles.tableCell}> <Text>{index + 1}</Text> </TableCell> <TableCell style={styles.tableCell}> <Text>内容</Text> </TableCell> <TableCell style={styles.tableCell}> <Text>内容</Text> </TableCell> </TableRow> ))} </Table> </View> {/* 自动分页 */} <View style={styles.section}> <Text>这是第二页</Text> </View> </Page> </Document> ); }; export default MyDocument; ``` 在上面的代码中,我们定义了一个 `<MyDocument>` 组件,其中包含了一个表格。表格使用了 `<Table>`、`<TableRow>`、`<TableCell>` 组件,每个单元格都有一个样式 `styles.tableCell`。我们使用了 `Array.from(Array(20).keys())` 来生成表格的多行,同时也演示了自动分页的效果。 最后,我们将 `<MyDocument>` 组件导出,然后在需要使用的地方引入即可。例如可以使用以下代码将 PDF 文件保存到本地: ```jsx import ReactPDF from '@react-pdf/renderer'; import MyDocument from './MyDocument'; const savePDF = async () => { const pdfBlob = await ReactPDF.renderToBlob(<MyDocument />); saveAs(pdfBlob, 'my-document.pdf'); }; ``` 在上面的代码中,我们使用了 `ReactPDF.renderToBlob()` 方法将 `<MyDocument>` 组件渲染成 PDF 文件,并将其保存到本地。需要注意的是,我们使用了第三方库 FileSaver.js 来实现下载操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值