vue实现生成pdf文件

主要就3个方法 exportReport outPutPdfFn isSplit

前置操作,我在vue原型上挂载了getPdf方法,方便复用

// 导出页面为PDF格式
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
Vue.prototype.getPdf = function (title, dom, emptyDomId) {
            // 注册getPdf方法,传入两个参数,此处使用了promise处理导出后的操作
            /*
            title: 导出文件名
            dom: 需要导出dom的id
             */
            return new Promise((resolve, reject) => {
                html2Canvas(dom, {
                    useCORS: true, // 由于打印时,会访问dom上的一些图片等资源,解决跨域问题!!重要
                    allowTaint: true // 允许跨域
                }).then(canvas => {
                    const contentWidth = canvas.width
                    const contentHeight = canvas.height
                    // 根据A4纸的大小,计算出dom相应比例的尺寸
                    const pageHeight = contentWidth / 592.28 * 841.89
                    let leftHeight = contentHeight
                    let position = 0
                    const imgWidth = 595.28
                    // 根据a4比例计算出需要分割的实际dom位置
                    const imgHeight = 592.28 / contentWidth * contentHeight
                    // canvas绘图生成image数据,1.0是质量参数
                    const pageData = canvas.toDataURL('image/jpeg', 1.0)
                    // a4大小
                    const PDF = new JsPDF('', 'pt', 'a4')
                    // 当内容达到a4纸的高度时,分割,将一整块画幅分割出一页页的a4大小,导出pdf
                    if (leftHeight < pageHeight) {
                        PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
                    } else {
                        while (leftHeight > 0) {
                            PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
                            leftHeight -= pageHeight
                            position -= 841.89
                            if (leftHeight > 0) {
                                PDF.addPage()
                            }
                        }
                    }
                    // 导出
                    PDF.save(title + '.pdf')
                    // 删除添加的空div

                    const emptyDom = document.getElementById(emptyDomId)
                    emptyDom.remove()
                    resolve(true)
                })
                    .catch(() => {
                        reject(false)
                    })
            })
        }

1 首先template部分就是,给你要到处pdf内容的部分加上一个id标识,用于获取这个盒子的dom对象,如图我这里的id是pdfDom

image.png

2 接着就是第一个方法exportReport,也就是按钮触发的方法,这个方法里面很简单,就获取了pdfDom这个盒子的dom对象,然后调用生成pdf的方法outPutPdfFn

exportReport() {
       const target = document.getElementById('pdfDom')
       this.outPutPdfFn('pdf文件名', target, 'item')
},

3 下面就是主要生成pdf文件的函数

        outPutPdfFn(title, target, itemClass) {
            const vm = this
            const A4_WIDTH = 592.28
            const A4_HEIGHT = 841.89

            vm.$nextTick(() => {
                // dom的id。

                const pageHeight = target.scrollWidth / A4_WIDTH * A4_HEIGHT
                // 获取分割dom,此处为class类名为item的dom
                const lableListID = document.getElementsByClassName(itemClass)
                // 进行分割操作,当dom内容已超出a4的高度,则将该dom前插入一个空dom,把他挤下去,分割
                for (let i = 0; i < lableListID.length; i++) {
                    const multiple = Math.ceil((lableListID[i].offsetTop + lableListID[i].offsetHeight) / pageHeight)
                    if (this.isSplit(lableListID, i, multiple * pageHeight)) {
                        const divParent = lableListID[i].parentNode // 获取该div的父节点
                        const newNode = document.createElement('div')
                        newNode.className = 'emptyDiv'
                        newNode.id = 'emptyDiv'
                        newNode.style.background = '#ffffff'
                        const _H = multiple * pageHeight - (lableListID[i].offsetTop + lableListID[i].offsetHeight)
                        newNode.style.height = _H + 30 + 'px'
                        newNode.style.width = '100%'
                        const next = lableListID[i].nextSibling // 获取div的下一个兄弟节点
                        // 判断兄弟节点是否存在
                        console.log(next)
                        if (next) {
                            // 存在则将新节点插入到div的下一个兄弟节点之前,即div之后
                            divParent.insertBefore(newNode, next)
                        } else {
                            // 不存在则直接添加到最后,appendChild默认添加到divParent的最后
                            divParent.appendChild(newNode)
                        }
                    }
                }
                // 传入title和dom标签,此处是 #content
                // 异步函数,导出成功后处理交互
                this.getPdf(title, target, 'emptyDiv').then(() => {
                    // 自定义等待动画关闭
                    this.$message({
                        type: 'success',
                        message: '导出成功'
                    })
                    this.detailSHow = false
                })
                this.$nextTick(() => {
                    const emptyDom = document.getElementById('emptyDiv')
                    emptyDom.remove()
                })


            })
        },

4 生成pdf函数中还涉及到了一个是否切割的函数判断,如下

 isSplit(nodes, index, pageHeight) {
            // 计算当前这块dom是否跨越了a4大小,以此分割
            if (nodes[index].offsetTop + nodes[index].offsetHeight < pageHeight && nodes[index + 1] && nodes[index + 1].offsetTop + nodes[index + 1].offsetHeight > pageHeight) {
                return true
            }
            return false
        },

至此一个简单的生成pdf功能就实现了,上述的方法基本都封装好了,使用上述的3个方法,只需要自己对需要生成pdf内容的盒子进行id的添加,将方法带入就可以了。

  • 10
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
您可以使用C#的iTextSharp库结合Vue.js和ASP.NET的身份验证来实现认证的Vue表单生成PDF文件的功能。以下是一个简单的示例代码: ```c# using iTextSharp.text; using iTextSharp.text.pdf; using System.IO; using System.Web; using System.Web.Mvc; using System.Web.UI; using System.Web.UI.WebControls; public class PdfController : Controller { [Authorize] // 添加身份验证特性 public ActionResult ConvertToPdf() { // 获取Vue.js生成的HTML代码 string vueHtml = GetVueHtml(); // 将HTML代码转换为PDF MemoryStream ms = new MemoryStream(); TextReader reader = new StringReader(vueHtml); Document document = new Document(PageSize.A4, 30, 30, 30, 30); PdfWriter writer = PdfWriter.GetInstance(document, ms); HTMLWorker worker = new HTMLWorker(document); document.Open(); worker.StartDocument(); worker.Parse(reader); worker.EndDocument(); worker.Close(); document.Close(); // 返回PDF文件 return File(ms.ToArray(), "application/pdf", "vue.pdf"); } private string GetVueHtml() { // 使用Vue.js生成带有表单的HTML代码 // 这里简单模拟一下 return "<html><head><title>Vue PDF</title></head><body><div id='app'><form><input type='text' name='name' placeholder='Name' required><input type='email' name='email' placeholder='Email' required><button type='submit'>Submit</button></form></div></body></html>"; } } ``` 需要注意的是,身份验证的实现需要根据具体的业务逻辑进行,可以使用ASP.NET的内置身份验证机制或第三方认证库。此外,iTextSharp库需要单独安装。可以使用NuGet包管理器来安装iTextSharp。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值