1. Технический отбор
1. После преобразования html в холст сгенерируйте изображения и экспортируйте pdf (выбрано в этой статье)
- Плагин HTML для холста:html2canvasПлагин, преобразующий HTML-код в Canvas;
- Холст генерирует PDF:jsPDFэто библиотека с открытым исходным кодом для создания PDF с использованием языка Javascript
2. HTML-код в pdf
wkhtmltopdfЭто плагин, который конвертирует HTML-код в pdf, большинство из которых используется в сценах таблиц.
Во-вторых, реализация технологии (на основе HTML2CANVAS и реализации JSPDF)
1. Установите плагин
npm i html2canvas -S
npm i jspdf -S
2. Регистрация и реализация инкапсуляции
Следующий инкапсулированный код может быть напрямую связан с файлом проекта для использования.Следующие моменты должны быть отмечены:
- Поскольку размер экспортируемого pdf-изображения должен быть фиксированным, необходимо добавить класс стиля .pdf-screen в экспортируемый dom, чтобы найти экспортируемый элемент, а затем изменить стиль экспортируемого элемента;
- Размер страницы экспорта фиксируется на размере a4;
/**
* @file 导出pdf文件
*/
import html2canvas from 'html2canvas';
import JsPDF from 'jspdf';
/* eslint-disable */
const PDF = {};
// a4
let a4Width = 595.28;
let a4Height = 841.89;
let defaultOptions = {
name: new Date().getTime(),
scale: window.devicePixelRatio * 2,
padding: 0,
width: 595.28 * 2,
allowTaint: true,
onclone: function (dom) {
let screen = dom.querySelector('.pdf-screen');
screen.style.width = 595.28 * 2 + 'px';
screen.style.padding = '10px';
}
}
PDF.install = function (Vue, rootOptions = {}) {
Vue.prototype.$pdf = function (dom, options = rootOptions) {
options = Object.assign(defaultOptions, options);
html2canvas(dom, options).then(canvas => {
let position = 0;
// 生成的画布元素宽高(需要收缩回原比例大小)
let canvasWidth = canvas.width / options.scale;
let canvasHeight = canvas.height / options.scale;
// 页面等比例缩放后宽高
let pageWidth = a4Width;
let pageHeight = (a4Width / canvasWidth) * canvasHeight;
//返回图片dataURL,参数:图片格式和清晰度(0-1)
let jpeg = canvas.toDataURL('image/jpeg', 1.0);
//方向默认竖直,尺寸ponits,格式a4[595.28,841.89]
let doc = new JsPDF('', 'pt', 'a4');
//有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
//当内容未超过pdf一页显示的范围,无需分页
if (canvasHeight < pageHeight) {
doc.addImage(jpeg, 'JPEG', 0, 0, pageWidth, pageHeight); // 从图片顶部开始打印
} else {
while (canvasHeight > 0) {
doc.addImage(jpeg, 'JPEG', 0, position, pageWidth, pageHeight);
canvasHeight -= pageHeight;
position -= a4Height;
//避免添加空白页
if (canvasHeight > 0) {
doc.addPage();
}
}
}
doc.save(options.name + '.pdf');
});
};
};
export default PDF;
3. Как использовать
// 在 main.js 中导入插件
import pdf from "./plugins/pdf";
// 注册插件
Vue.use(PDF);
// 在需要导出pdf的函数中调用
// dom是需要导出的最外层元素
this.$pdf(dom, options);
// 使用案例(该配置可参考HTML2CANVAS相关配置)
this.$pdf(this.$refs.screen, {
name: 'filename', // 导出文件名
scale: 2, // 导出文件清晰度,值越大清晰度越高,文件体积越大(默认值为设备dpr*2)
ignoreElements: (element) => { // 忽略渲染元素(通过查询dom元素,不局限于类名查询)
if (element.className.indexOf('className') !== -1) {
return true;
}
}
});
В-третьих, возникшие проблемы и пути их решения.
1. Проблема усечения содержимого PDF (будет решена)
Описание проблемы: Поскольку принцип реализации заключается в преобразовании html в канвас и последующей генерации картинки для экспорта в pdf-файл, содержимое длинного изображения, генерируемого канвой, будет обрезано в процессе листания и сохранения;
2. Проблема разрешения файла экспорта PDF (решена)
Описание проблемы: разрешение изображения, генерируемого холстом, слишком низкое;
Решение: элемент DOM можно масштабировать пропорционально, а затем можно сгенерировать изображение и экспортировать его в файл pdf;