vue页面转Html,word,pdf?

193 阅读2分钟

前置

下载 htmlcanvas.js,jsPdf.js,html-docx.js,FileSaver.js

拿到Html字符

  • 我这里是以包含 echarts的案例为基准的,如果你不需要则可以把echarts部分删掉
  • 这里返回的是一个html字符串
export const useExport = (app: Ref<HTMLElement>) => {
//如果要转word的话 html头部是有一点区别的
const createHtmlString = (parmas = {}, isOffice = true) => {
    const data = Object.assign(
      {
        headStr: document.head.innerHTML,
        bodyStr: app.value.outerHTML,//这个容器就是内容部分,所以你需要一个容器把你的内容包含起来
        scriptStr: '',//js脚本字符
      },
      parmas,
    )
    //这里之所以这么写,vue在解析模板的时候 这些关键字会让内部报错
    const a = ['b', 'o', 'd', 'y'].join(',').replaceAll(',', '')
    const b = ['h', 't', 'm', 'l'].join(',').replaceAll(',', '')
    const s = ['s', 'c', 'r', 'i', 'p', 't'].join(',').replaceAll(',', '')
    const top = isOffice
      ? `<html xmlns:o=\'urn:schemas-microsoft-com:office:office\' xmlns:w=\'urn:schemas-microsoft-com:office:word\' xmlns=\'http://www.w3.org/TR/REC-html40\'>`
      : '<html>'
    return `
            ${top}
            <head>
             ${data.headStr}
             <style>
            table { 
                    border-right:1px solid #000000;
                    border-bottom:1px solid #000000;
                    border-left:1px solid #000000;
                    border-top:1px solid #000000;
                }
                table th  {
                  border-left:1px solid #000000;
                  border-top:1px solid #000000;
                  border-right:1px solid #000000;
                  border-bottom:1px solid #000000;
                }
                table td {
                    border-left:1px solid #000000;
                    border-top:1px solid #000000;
                    border-right:1px solid #000000;
                    border-bottom:1px solid #000000;
                }
             </style>
             </head>
            <${a}>
                ${data.bodyStr}
            </${a}>
             <${s} src="https://cdn.staticfile.org/echarts/4.3.0/echarts.min.js" ></${s}>
              <${s}> 
              //echarts部分
                window.task = []
                window.onload = ()=>{
                    window.task.forEach(item=>{
                        item()
                    })
                }
              </${s}>
            <${s}> ${data.scriptStr}</${s}>
            </${b}>
      `
  }
  return {
  createHtmlString
  }
}

示例

<template>
<div ref="reportDom"></div>
</template>
<script lang="ts" setup>
const reportDom = ref()
const { createHtmlString } = useExport(reportDom)
 const str = createHtmlString(
        {
          scriptStr: completeCode.value,
        },
        false,
      )
</script>

转html文件

//str   html字符串
const content = new Blob([str])
saveAs(content, `${fileName}.html`)

转word

 const converted = htmlDocx.asBlob(str)
saveAs(converted, `${fileName}.docx`)

转pdf

 let domparser = new DOMParser()
          let doc = domparser.parseFromString(str, 'text/html')
          pdfDom.value.innerHTML = doc.body.children[0].outerHTML
          nextTick(() => {
            const options = {
              format: 'a4',
              dpi: 192, //dpi属性的值为192,表示图像的分辨率
              scale: 1, //scale属性的值为2,表示图像的缩放比例。
              backgroundColor: '#fff', //backgroundColor属性的值为"#F1F6FE",表示图像的背景颜色。
            }
            html2canvas(pdfDom.value, options).then((canvas) => {
              var contentWidth = canvas.width //获取Canvas(上面元素id 'layout-wrapper')对象的宽度
              var contentHeight = canvas.height || 1024 //获取Canvas(上面元素id 'layout-wrapper')对象的高度
              const pdf = new jsPDF('1', 'pt', [contentWidth, contentHeight]) //创建一个新的PDF对象,参数包括页面格式('1'表示A4纸张)、单位('pt')和页面尺寸([contentWidth, contentHeight])
              var pageData = canvas.toDataURL('image/jpeg', 1.0) //将Canvas对象转换为JPEG格式的数据,并将其存储在pageData变量中。1.0表示图片质量
              pdf.addImage(pageData, 'JPEG', 0, 0, contentWidth, contentHeight) //将JPEG格式的图片添加到PDF文件中,图片的左上角坐标为(0, 0),宽度为contentWidth,高度为contentHeight
              pdf.save('test.pdf')
            })
          })