Vue3 在线 PDF 编辑 1.0 保存、下载

各位开发者朋友们!上次给大家分享了 PDF 批注功能的实现思路,相信大家对项目有了更深入的理解。今天,咱们接着深挖 基于 Vue3 的在线 PDF 编辑 1.0 项目诞生记 中剩余的核心功能 ------ 保存和下载,看看它们背后的技术细节。

基于 fabric-Canvas 的保存功能:便捷的数据生成

在这个项目里,保存功能借助 fabric-Canvas 变得简单高效。利用其内置方法,能轻松生成用于保存批注信息的 JSON 数据。代码如下:

ini 复制代码
const save = (fabricCanvasObj: any) => {
    let fabricJsonObj: any = {};
    for (let key in fabricCanvasObj) {
        const jsonObj = fabricCanvasObj[key].toJSON();
        if (jsonObj.objects.length > 0) {
            fabricJsonObj[key] = jsonObj;
        }
    }
    return fabricJsonObj;
};

这段代码遍历 fabricCanvasObj 中的每个画布实例,调用toJSON方法获取其包含批注信息的 JSON 数据。若画布上有批注(即jsonObj.objects.length > 0),就将该画布的 JSON 数据存入fabricJsonObj,最后返回这个包含所有有效批注信息的对象。

保存得数据:

基于 pdf-lib 的下载功能:融合 PDF 与批注的魔法

下载功能则由pdf-lib库来 "大显身手"。实现过程中,先把批注所在的canvas转化为图片格式,再借助pdf-lib的embedPng方法,将原始 PDF 和批注图片合并为一个新的 PDF 文件。具体代码如下:

ini 复制代码
const down = async (pdfUrl: string, fabricCanvasObj: any) => {
    const response = await fetch(pdfUrl);
    const pdfData = await response.arrayBuffer();
    const pdfDoc = await PDFDocument.load(pdfData);
    const pages = pdfDoc.getPages();
    for (let key in fabricCanvasObj) {
        const jsonObj = fabricCanvasObj[key].toJSON();
        if (jsonObj.objects.length > 0) {
            const dataURL = fabricCanvasObj[key].toDataURL({
                format: 'png',
                quality: 1
            });
            const currentPageIndex: number = parseInt(key.split("_")[1], 10);
            const page = pages[currentPageIndex];
            const annotImage = await pdfDoc.embedPng(dataURL);
            const { width, height } = page.getSize();
            page.drawImage(annotImage, {
                x: 0,
                y: 0,
                width: width,
                height: height,
                opacity: 1,
            });
        }
    }
    const modifiedPdfBytes = await pdfDoc.save();
    const blob = new Blob([modifiedPdfBytes], { type: 'application/pdf' });
    const url = URL.createObjectURL(blob);
    return url;
};

代码首先通过fetch获取原始 PDF 数据,用PDFDocument.load加载为 PDF 文档对象。接着遍历fabricCanvasObj,对于有批注的画布,将其转化为 PNG 格式的dataURL。根据画布 ID 解析出对应的 PDF 页面索引,获取该页面并使用embedPng嵌入批注图片,按照页面尺寸绘制。最后保存修改后的 PDF 文档,生成 Blob 对象并创建 URL 返回,完成带批注 PDF 的下载准备。

批注后下载得PDF

目前,1.0 版本的功能已全部为大家分享完毕。下周,我们将开启 2.0 版本的筹备工作,计划添加缩放、图片插入等实用功能。欢迎各位开发者前往 项目仓库 获取源码研究,也希望大家在评论区畅所欲言,一起探讨功能优化方向,携手完善项目生态!

相关推荐
WangHappy7 小时前
不写 Canvas 也能搞定!小程序图片导出的 WebView 通信方案
前端·微信小程序
李剑一7 小时前
要闹哪样?又出现了一款新的格式化插件,尤雨溪力荐,速度提升了惊人的45倍!
前端·vue.js
闲云一鹤7 小时前
Git LFS 扫盲教程 - 你不会还在用 Git 管理大文件吧?
前端·git·前端工程化
阿虎儿8 小时前
React Context 详解:从入门到性能优化
前端·vue.js·react.js
Sailing8 小时前
🚀 别再乱写 16px 了!CSS 单位体系已经进入“计算时代”,真正的响应式布局
前端·css·面试
喝水的长颈鹿8 小时前
【大白话前端 03】Web 标准与最佳实践
前端
爱泡脚的鸡腿8 小时前
Node.js 拓展
前端·后端
左夕9 小时前
分不清apply,bind,call?看这篇文章就够了
前端·javascript
Zha0Zhun10 小时前
一个使用ViewBinding封装的Dialog
前端
兆子龙10 小时前
从微信小程序 data-id 到 React 列表性能优化:少用闭包,多用 data-*
前端