前端頁面直接轉換為PDF文件流


一、代碼實例

// 導出頁面為PDF格式

import html2Canvas from 'html2canvas'

import JsPDF from 'jspdf'

import $jQuery from 'jquery'

import Axios from '@/axios'

import { getServerPath } from '@/constants/CommCreditClientApi'

export default {

  install(Vue, options) {

    Vue.prototype.uploadDom = function (domId, data) {

      this.$message.info('上傳開始')

      let vm = this

      // 將base64轉換為文件對象

      let dataURLtoFile = function (dataurl, filename) {

        let arr = dataurl.split(',')

        let mime = arr[0].match(/:(.*?);/)[1]

        let bstr = atob(arr[1])

        let n = bstr.length

        let u8arr = new Uint8Array(n)

        while (n--) {

          u8arr[n] = bstr.charCodeAt(n)

        }

        // 轉換成file對象

        return new File([u8arr], filename, { type: mime })

        // 轉換成成blob對象

        // return new Blob([u8arr],{type:mime})

      }

      // pdf文件上傳

      let uploadPdf = function (file) {

        // let url =''

        getServerPath().then(url => {

          let requestUrl = 'http://' + url + '/oms/credit/file/param/common/paramImageManager'

          console.log(requestUrl)

          let formData = new FormData()

          let fileList = []

          fileList.push(file)

          formData.append('fileList', file)

          // 組裝入參--start

          formData.append('batchClass', 'htmlToPdf')

          formData.append('userName', localStorage.getItem('userName'))

          formData.append('branch', JSON.parse(localStorage.getItem('userInfo')).deptNo.toString())

          formData.append('company', JSON.parse(localStorage.getItem('userInfo')).company.toString())

          formData.append('operateFlag', 'A')

          console.log(data)

          formData.append('attachId', data.businessSeqNo)

          formData.append('clientNo', data.clientNo)

          formData.append('channel', data.channel)

          formData.append('registerBranch', JSON.parse(localStorage.getItem('userInfo')).deptNo.toString())

          formData.append('registerUserId', localStorage.getItem('userName'))

          formData.append('lastChangeBranch', JSON.parse(localStorage.getItem('userInfo')).deptNo.toString())

          formData.append('lastChangeUserId', localStorage.getItem('userName'))

          // 組裝入參--end

          Axios({

            method: 'post',

            url: requestUrl,

            data: formData

          }).then(res => {

            vm.$message.info('上傳完成')

          }).catch(() => {

            vm.$message.error('上傳失敗')

          })

        })

      }

      let pdfName = 'test.pdf'

      let element = $jQuery(`#${domId}`)

      var w = element.width() // 獲得該容器的寬

      var h = element.height() // 獲得該容器的高

      // var offsetTop = element.offset().top // 獲得該容器到文檔頂部的距離

      // var offsetLeft = element.offset().left // 獲得該容器到文檔最左的距離

      var canvas = document.createElement('canvas')

      canvas.width = w

      canvas.height = h

      var context = canvas.getContext('2d')

      var scale = 1

      context.scale(1, 1)

      // context.translate(-offsetLeft, -offsetTop)



      var opts = {

        scale: scale,

        canvas: canvas,

        width: w,

        height: h,

        useCORS: true,

        background: '#FFF',

        allowTaint: false

      }



      html2Canvas(element[0], opts).then(function (canvas) {

        let pdf = new JsPDF('p', 'mm', 'a4') // A4紙,縱向

        let ctx = canvas.getContext('2d')

        let a4w = 190

        let a4h = 277 // A4大小,210mm x 297mm,四邊各保留10mm的邊距,顯示區域190x277

        let imgHeight = Math.floor(a4h * canvas.width / a4w) // 按A4顯示比例換算一頁圖像的像素高度

        let renderedHeight = 0

        while (renderedHeight < canvas.height) {

          let page = document.createElement('canvas')

          page.width = canvas.width

          page.height = Math.min(imgHeight, canvas.height - renderedHeight) // 可能內容不足一頁

          // 用getImageData剪裁指定區域,並畫到前面創建的canvas對象中

          page.getContext('2d').putImageData(ctx.getImageData(0, renderedHeight, canvas.width, Math.min(imgHeight, canvas.height - renderedHeight)), 0, 0)

          pdf.addImage(page.toDataURL('image/jpeg', 1.0), 'JPEG', 10, 10, a4w, Math.min(a4h, a4w * page.height / page.width)) // 添加圖像到頁面,保留10mm邊距

          renderedHeight += imgHeight

          if (renderedHeight < canvas.height) {

            pdf.addPage() // 如果后面還有內容,添加一個空頁

          }

        }

        // pdf.save(pdfName)

        // 將pdf輸入為base格式的字符串

        let buffer = pdf.output('datauristring')

        // 將base64格式的字符串轉換為file文件

        let myfile = dataURLtoFile(buffer, pdfName)

        uploadPdf(myfile)

        console.log(myfile)

      })

    }

  }

}

formData里存放的是要傳給后端的數據。后端接收到的文件流(即formData.fileList)是MultipartFile數組形式;這里需要注意一點,如果是單文件,可以直接將file放入fileList傳輸,后端依然可以像單批次多文件一樣進行處理。除文件流數組外的參數,通過HttpServletRequest類型的入參進行接收,通過request.getParameter(key)函數獲取值。

  

二、實現原理

 用到了html2Canvas和JsPDF這兩個插件。首先通過html2Canvas將頁面轉化為canvas元素,並進行裁切,然后再轉化為文件流。

三、參考鏈接

以上代碼綜合了以下三篇文章。

https://blog.csdn.net/bing823506390/article/details/109673360

https://blog.csdn.net/pratise/article/details/79249943

https://www.imooc.com/article/268668/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM