2020-10-13-x
Xplorist Lv6

2020-10-13

todo-list

  • yy
  • html转pdf

record-list

  • 整个耗材验证需求单的开发难点就在于html转pdf

  • 技术文档最重要最基础的是表明自己的技术栈,开发环境以及软件版本,这样才是严谨的文档作品

  • 自己要开始设计一个自己的md文档标准格式

  • vue-html2pdf –> html2pdf.js –> html2canvas + jsPDF

  • 选择了html2canvas + jsPDF的方式来将html转成pdf,安装wps_pdf来查看生成的pdf的效果,效果还行

  • 使用html2canvas + jsPDF的方式关键代码,div超出屏幕后,没有下面的代码,保存按钮在最底部,会导致pdf显示不全

    1
    2
    document.documentElement.scrollTop = 0
    document.body.scrollTop = 0
  • 上面的原因分析:主要是计算的时候是从窗口顶部到元素底部,不scrollTop=0的话,高度就少了窗口上隐藏进去的那一部分高度

  • htmlToPdf.js完整代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    // htmlToPdf.js
    import html2Canvas from 'html2canvas'
    import JsPDF from 'jspdf'

    export default {
    install(Vue, options) {
    window.console.log(options)
    Vue.prototype.$getPdf = function (id, title) {
    // 获取当前浏览器滚动条的宽度,原理是设置一个不可见的div,查看设置scorll前后的宽度差
    function getScrollWidth() {
    var noScroll, scroll
    var oDiv = document.createElement('DIV')
    oDiv.style.cssText = 'position:absolute; top:-1000px; width:100px; height:100px; overflow:hidden;'
    noScroll = document.body.appendChild(oDiv).clientWidth
    oDiv.style.overflowY = 'scroll'
    scroll = oDiv.clientWidth
    document.body.removeChild(oDiv)
    return noScroll - scroll
    }

    const SIZE = [595.28, 841.89] // a4宽高
    let node = document.querySelector(`#${id}`)
    document.documentElement.scrollTop = 0
    document.body.scrollTop = 0

    let nodeW
    if (getScrollWidth()) {
    nodeW = node.clientWidth - (17 - getScrollWidth())
    } else {
    nodeW = node.clientWidth
    }
    // let nodeW = node.clientWidth
    // 单页高度
    let pageH = nodeW / SIZE[0] * SIZE[1]
    window.console.log(pageH)
    let modules = node.children
    for (let i = 0, len = modules.length; i < len; i++) {
    let item = modules[i]
    let beforeH = item.offsetTop
    let afterH = beforeH + item.clientHeight
    let currentPage = parseInt(beforeH / pageH)
    // div距离父级的高度是pageH的倍数x,但是加上自身高度之后是pageH的倍数x+1,说明被切割
    if (currentPage !== parseInt(afterH / pageH)) {
    // 上一个元素底部距离父级的高度
    let lastItemAftarH = modules[i - 1].offsetTop + modules[i - 1].clientHeight
    let fill = pageH - lastItemAftarH % pageH
    item.style.marginTop = fill + 'px'
    }
    }

    html2Canvas(node, {
    // allowTaint: true,
    useCORS: true, // allowTaint与useCORS看情况二选一,设置 useCORS 为 true,即可开启图片跨域
    scale: 2, // 设置 scale 为 2 及以上,即可支持高分屏
    width: node.scrollWidth + getScrollWidth()
    }).then(function (canvas) {
    //document.body.appendChild(canvas)
    let contentWidth = canvas.width
    let contentHeight = canvas.height
    // 一页pdf显示html页面生成的canvas高度
    let pageHeight = contentWidth / SIZE[0] * SIZE[1]
    // 未生成pdf的html页面高度
    let leftHeight = contentHeight
    // pdf页面竖向偏移
    let position = 0
    // 横向页边距
    let sidesway = 0
    // html页面生成的canvas在pdf中图片的宽高
    let imgWidth = SIZE[0] - sidesway * 2
    let imgHeight = imgWidth / contentWidth * contentHeight
    let pageData = canvas.toDataURL('image/jpeg', 1.0)
    let PDF = new JsPDF('', 'pt', 'a4')
    if (leftHeight < pageHeight) {
    PDF.addImage(pageData, 'JPEG', sidesway, position, imgWidth, imgHeight)
    } else {
    while (leftHeight > 0) {
    PDF.addImage(pageData, 'JPEG', sidesway, position, imgWidth, imgHeight)
    leftHeight -= pageHeight
    position -= SIZE[1]
    if (leftHeight > 0) {
    PDF.addPage()
    }
    }
    }

    PDF.save(title + '.pdf')
    })
    }
    }
    }

  • main.js

1
2
3
4
// main.js
import htmlToPdf from '@/utils/htmlToPdf'

Vue.use(htmlToPdf)
  • 引用方代码
1
2
3
4
5
6
7
8
9
<html>
<button v-on:click="saveToPDF()">保存为PDF</button>
</html>

<script>
saveToPDF () {
this.$getPdf('pdf', this.title);
},
</script>

home-record-list

  • x

reference-site-list

html to pdf

html

vscode

 评论