vue3 富文本编辑器文本转pdf文件并下载

原理:富文本转pdf其实就是将txt文本插入html元素中,再将使用html2Canvas画布生成图片,最后在使用jspdf插件将图片转为pdf文件

遇到问题:会出现黑色背景以及分页时文字会被截断

1、需要安装三个依赖

npm install wangeditor --save
npm install jspdf --save
npm install  html2canvas --save

2、vue文件使用编辑器

<template>
  <div>
    <!-- 编辑器 -->
    <div ref="domRef" class="bg-white dark:bg-dark z-1"></div>
    <!-- 下载 -->
    <n-button type="info" @click="savaBtnSubmit()">下载</n-button>
    <!-- pdf文本 -->
    <div id="pdfDom" style="padding: 0 20px; width: 847px" class="absolute -top-999px"></div>
  </div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import WangEditor from 'wangeditor'; // 编辑器插件
import { getPdf } from '@/utils';

const content = ref();
const editor = ref();
const domRef = ref();

// 创建编辑器实例
function renderWangEditor() {
  editor.value = new WangEditor(domRef.value);
  // 监听内容变化事件
  editor.value.config.onchange = newHtml => {
    content.value = newHtml; // newHtml 等同于 editor.value.txt.html();
  };
  editor.value.create();
}
// 下载
async function savaBtnSubmit() {
  getPdf('文档名称', content.value);
}
onMounted(() => {
  renderWangEditor();
});
</script>

        补充:如果只需要将html转为pdf,只需要下方代码
        <div id="pdfDom" style="padding: 0 20px; width: 847px"></div>
        <n-button type="info" @click="savaBtnSubmit()">下载</n-button>
        function savaBtnSubmit() {
          getPdf('文档名称');
        }

3、新建htmlToPdf.js文件,

import html2Canvas from 'html2canvas'
import jsPDF from 'jspdf'

export function getPdf(title, htmlString) {
  let douTxt = document.querySelector('#pdfDom') // 获取元素
  douTxt.innerHTML = htmlString // 元素插入富文本内容

  html2Canvas(douTxt, {
    allowTaint: true,
    // taintTest: false,
    logging: false,
    useCORS: true,
    // dpi: window.devicePixelRatio * 4, //将分辨率提高到特定的DPI 提高四倍
    scale: 4, //按比例增加分辨率
  }).then((canvas) => {
    // 未生成pdf的html页面高度
    let leftHeight = canvas.height

    let a4Width = 595.28 //
    let a4Height = 841.89 //A4大小进行像素转换 一页pdf显示html页面生成的canvas高度
    let a4HeightRef = Math.floor((canvas.width / a4Width) * a4Height) //pdf页面偏移

    let position = 0

    let pageData = canvas.toDataURL('image/jpeg', 1.0)

    let pdf = new jsPDF('p', 'pt', 'a4') // A4纸,纵向
    let index = 1,
      canvas1 = document.createElement('canvas'),
      height
    pdf.setDisplayMode('fullwidth', 'continuous', 'FullScreen')

    function createImpl(canvas) {
      if (leftHeight > 0) {
        index += 1

        let checkCount = 0
        if (leftHeight > a4HeightRef) {
          let i = position + a4HeightRef
          for (i = position + a4HeightRef; i >= position; i--) {
            let isWrite = true
            for (let j = 0; j < canvas.width; j++) {
              let 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)
          if (height <= 0) {
            height = a4HeightRef
          }
        } else {
          height = leftHeight
        }

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

        console.log(index, 'height:', height, 'pos', position)

        let ctx: any = canvas1.getContext('2d')
        ctx.drawImage(canvas, 0, position, canvas.width, height, 0, 0, canvas.width, height)

        // let pageHeight = Math.round((a4Width / canvas.width) * height) // pdf.setPageSize(null, pageHeight)
        if (position != 0) {
          pdf.addPage()
        }
        pdf.addImage(
          canvas1.toDataURL('image/jpeg', 1.0),
          'JPEG',
          0, // 距左方0
          0, // 距上方0
          a4Width,
          (a4Width / canvas1.width) * height
        )
        leftHeight -= height
        position += height
        if (leftHeight > 0) {
          setTimeout(createImpl, 500, canvas)
        } else {
          pdf.save(title + '.pdf')
        }
      }
    } //当内容未超过pdf一页显示的范围,无需分页

    if (leftHeight < a4HeightRef) {
      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);
      }
    }
  })
}

        补充:如果只需要将html元素转为pdf,该文件修改这两行代码

               getPdf(title, htmlString) 函数传入的值改为getPdf(title)

              douTxt.innerHTML = htmlString // 元素插入富文本内容

4、最终实现效果

  • 8
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值