vue使用jspdf導出表格(非html2canvas導出)

看了所有的博客都是用html2canvas導出的,畫質都很模糊,它的原理是將你要導出的頁面放進一個dom,然後利用這個插件把這個dom轉換爲一張canvas圖片,然後塞進pdf,到後導出,畫質模糊,但是它功能強大,能導出所有元素(圖片、文章等等)爲pdf。


我今天要說的是將頁面上已有的table,或者後端返回的table數據,導出爲pdf,包括上面所說的將頁面導出爲pdf,寫成了示例,這個是我的github示例地址,克隆項目到本地,按照下面的README.md進行啓動,裏面註釋都很詳細,不明白可以私信,歡迎star。


我簡單說一下這個示例,就是將頁面上已有的table,或者後端返回的table數據,導出爲pdf,如下所示是將頁面上已有table導出 :
在這裏插入圖片描述


說一下實現過程,這說的是我的示例實現過程,有小夥伴要用的話,可以直接克隆我的項目,然後按照README.md啓動就好:

下載依賴

import html2Canvas from 'html2canvas' // cnpm install --save html2canvas    這是將頁面dom都可以導出的,本身意思就是將html轉爲canvas圖片
import JsPDF from 'jspdf'      //  cnpm install jspdf --save        
import 'jspdf-autotable'         //  cnpm install jspdf-autotable    // 這是渲染pdf-table用到的, 下載完之後要修改源代碼,否則表頭還是中文亂碼,至於如何操作看github

html

因爲我兩種方法都寫了,所以在helloworld.vue裏面寫上兩種方法,註釋已經很清晰了:

<template>
  <div class="hello">
  	   <!-- 這是第一種 -->
      <button @click="getPdf('范德薩發的')">用html2canvans導出文件PDF</button>
      <p>我的優點:可以導出任何東西,圖片或者文章或者表格,總之就是將你要導出的東西轉成一張圖片導出</p>
      <p>我的缺點:導出畫質模糊</p>
      <!-- 這是要導出的dom -->
      <div id="pdfDom">
          <table border="1">
              <tr>
                  <td>第三方</td>
                  <td>虛線</td>
              </tr>
              <tr>
                  <td>是發v</td>
                  <td>程序</td>
              </tr>
          </table>
          <img src="../assets/logo.png">
          <div style="font-size: 20px;">
              <p>哎呀呀呀</p>
              <p>你瞅啥</p>
              <p>瞅你咋地</p>
          </div>
      </div>



      <p style="line-height: 180px;background: #ccc;color: #000;">------------------------------------------------------------------------------我是一條分割線--------------------------------------------------------------------------------------------------------</p>
      
      
      
      
      <!-- 這是第二種 -->
      <button @click="getPdfTable('tableDom' ,'吃的飯')">用autotable導出表格文件pdf</button>
      <p>我的優點:可以導出頁面上的table,或者後臺動態返回的table數據,畫質清晰</p>
      <p>我的缺點:只能導出table</p>
      <!-- 這是要預覽pdf的地方 -->
      <iframe id="tableDom" width="100%" height="500px">
          
      </iframe>
      <div>
      	  <!-- 這是要導出的頁面上的table -->
          <table id="basic-table" border="2">
                <tr>
                    <td>芙蓉</td>
                    <td>方如果他不</td>
                    <td>大V發的</td>
                </tr>
                <tr>
                    <td>個人個投入</td>
                    <td>不放過會讓你</td>
                    <td>存放的</td>
                </tr>
                <tr>
                    <td>如果他人吧</td>
                    <td>虧空</td>
                    <td>輔導班</td>
                </tr>
          </table>
      </div>
  </div>
</template>

<script>
export default {
    name: 'HelloWorld',
    data () {
      return {
        msg: 'Welcome to Your Vue.js App',
      }
    }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.hello >p{
  color: red;
}
#pdfDom{
  width: 100%;
  border: 1px solid;
}
</style>

獲取中文字體

這個不詳細說了,在項目下static文件夾下新建一個font文件夾,放進去一個font.js文件,這個js文件裏面放你獲取的中文字體文件base64,具體怎麼獲取看這篇博文講得很清楚了

寫導出方法

依賴已經下載了,然後在項目src文件夾下新建一個文件夾until,放這個方法的htmlToPdf.js文件,註釋都寫全了:

import html2Canvas from 'html2canvas' // cnpm install --save html2canvas
import JsPDF from 'jspdf'      //  cnpm install jspdf --save
import 'jspdf-autotable'         //  cnpm install jspdf-autotable    // 下載完之後要修改源代碼,否則表頭還是中文亂碼
import moo from '../../static/font/font'     // 中文字體文件
export default{
  install (Vue, options) {
    // ====第一種--使用html2canvas導出pdf=============================================================================================================
    Vue.prototype.getPdf = function (titles) {
      var title = titles
      html2Canvas(document.querySelector('#pdfDom'), {      // 導出的dom可以傳參
        allowTaint: true
    }).then(function (canvas) {
        let contentWidth = canvas.width
        let contentHeight = canvas.height
        let pageHeight = contentWidth / 592.28 * 841.89
        let leftHeight = contentHeight
        let position = 0
        let imgWidth = 595.28
        let imgHeight = 592.28 / contentWidth * contentHeight
        let pageData = canvas.toDataURL('image/jpeg', 1.0)
        let PDF = new JsPDF('', 'pt', 'a4')
        PDF.setFontSize(22);    //  因爲畫質模糊,所以這裏字體設置大一些,就清晰了
        // pageData    
        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')
      }
      )
    },

    // =======第二種 --使用動態數據、或者頁面數據導出pdf表格==============================================================================================
    Vue.prototype.getPdfTable = function (dom ,titles) {
        var doc = new JsPDF('p', 'pt'); // 獲取實例
        var res = doc.autoTableHtmlToJson(document.getElementById("basic-table"));    // 這是獲取頁面已有table的數據導出  ,順序不能亂放,要不就會亂碼,獲取的basic-table可以傳參
        
        // ===============================  設置字體
        doc.addFileToVFS('pingfang.ttf', moo)
        doc.addFont('pingfang.ttf', 'b', 'normal');

        doc.setFont('b');
        // ===============================
        
        // doc.autoTable({                   // 這是動態獲取後臺table數據數據導出,如果用這個,則註釋掉 46行、69-79行即可
        //     styles: { fillColor: [0, 0, 0], font: 'b', textColor: [255,255,255] },
        //     theme: 'grid',
        //     body: [           // 可以傳參
        //         { europe: '大幅度', america: '更豐富', asia: '防輻射' },
        //         { europe: 'Norway', america: 'Mexico', asia: 'Japan' },
        //     ],
        //     columns: [       // 可以傳參
        //         { header: '表頭1', dataKey: 'europe' },
        //         { header: '表頭2', dataKey: 'asia' },
        //         { header: '表頭3', dataKey: 'america' },
        //     ],
        // })

        doc.autoTable({                  // 這是獲取頁面已有table的數據導出  ,順序不能亂放,要不就會亂碼
            styles: { fillColor: [0, 0, 0], font: 'b', textColor: [255,255,255] , halign: 'center',},    // 樣式
            theme: 'grid',           // 主題
            startY: 100,          // 距離上邊距離
            body: res.data,        // tableDate
            columns: [          // 表頭// 可以傳參
                { header: '表頭1', dataKey: 'europe' },
                { header: '表頭2', dataKey: 'asia' },
                { header: '表頭3', dataKey: 'america' },
            ],
        })
        
        doc.text(40, 30, '個人號還挺好')      //  渲染title  // 可以傳參
        document.getElementById(dom).src = doc.output('datauristring');   // 渲染pdf
        doc.save("table.pdf");   // 導出pdf   // 名字可以傳參
    }
  }
}

全局掛載

方法寫好了以後,在全局使用:

// main.js
import htmlToPdf from '@/untils/htmlToPdf'
Vue.use(htmlToPdf

到這就完了,其實過程中還是要一遍遍看官方的github,畢竟這是歪果仁寫的,也沒有什麼中文文檔,全英文介紹,而且示例還要找來找去,再一個就是他這個依賴衆多,你要看好幾個依賴的github文檔才能同時明白

再說一遍,要一遍一遍又一遍,重要的事情說三遍,看文檔!!!直到你看明白。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章