模块文件
import MarkdownIt from 'markdown-it'
import html2pdf from 'html2pdf.js'
const markdown = new MarkdownIt({
breaks: true
})
function addClassToRule(md, ruleName, cls) {
const original = md.renderer.rules[ruleName] || function(tokens, idx, options, env, renderer) {
return renderer.renderToken(tokens, idx, options)
}
md.renderer.rules[ruleName] = function(tokens, idx, options, env, renderer) {
const token = tokens[idx]
const old = token.attrGet('class') || ''
token.attrSet('class', `${old} ${cls}`.trim())
return original(tokens, idx, options, env, renderer)
}
}
[
'paragraph_open',
'heading_open',
'list_item_open',
'blockquote_open',
'tr_open'
].forEach(rule => addClassToRule(markdown, rule, 'pdf-safe'))
const originalFence = markdown.renderer.rules.fence || function(tokens, idx, options, env, renderer) {
return renderer.renderToken(tokens, idx, options)
}
markdown.renderer.rules.fence = function(tokens, idx, ...args) {
const raw = originalFence(tokens, idx, ...args)
return `<div class="pdf-safe">${raw}</div>`
}
const unicodeMap = {
':': ':',
'(': '(',
')': ')',
};
const resultReplace = (text) => {
let result = text.replace(/[\uff1a\uff08\uff09]/g, (match) => {
return unicodeMap[match];
});
return result;
};
export const showHtml = (value) => {
return resultReplace(markdown.render(value))
}
export const exportPDF = async (element, fileName) => {
element.querySelectorAll('table').forEach(t => {
t.style.tableLayout = 'fixed'
t.style.width = '100%'
})
const opt = {
margin: 10,
filename: `${fileName}.pdf`,
image: {
type: 'jpeg',
quality: 0.98
},
html2canvas: {
scale: 2,
useCORS: true
},
jsPDF: {
unit: 'mm',
format: 'a4',
orientation: 'portrait'
}
}
await html2pdf().set(opt).from(element).save()
}
使用方法
<template>
<div id="pdfArea" style="white-space: pre-wrap;overflow-y: auto; "
v-html="showHtml(content)">
</div>
<button @click="ExportPDF">导出为PDF</button>
</template>
import {
ref,
} from 'vue'
import {
exportPDF,showHtml
} from '@/tools/methods'
const content = ref('')
const topic = ref('')
const fetchDetail = async () => {
let data = JSON.parse(localStorage.getItem('talentMark'))
content.value = data.md_tmp_file
topic.value = data.name
}
fetchDetail()
const ExportPDF = async () => {
const element = document.getElementById('pdfArea')
exportPDF(element, topic.value)
}
main.scss
.pdf-safe {
page-break-inside: avoid;
}