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 版本的筹备工作,计划添加缩放、图片插入等实用功能。欢迎各位开发者前往 项目仓库 获取源码研究,也希望大家在评论区畅所欲言,一起探讨功能优化方向,携手完善项目生态!

相关推荐
RONIN8 分钟前
vue组件、组件生命周期、组件分离模块化
前端·vue.js
小强19889 分钟前
HTML5语义化标签:从`div`到`article`与`section`的进化之路
前端
RONIN10 分钟前
vue开发环境与基础语法、计算属性、侦听属性
前端·vue.js
WayneYang16 分钟前
JavaScript ES6+ (ES2015~ES2024) 全特性整理
前端·javascript
逆光如雪17 分钟前
移动端border-left 和 width:1px,同样写1px为什么粗细不同?
前端·css
千寻girling19 分钟前
被内推的面试 , 第一次
java·前端·python·面试·职场和发展·typescript·node.js
JustNow_Man30 分钟前
Bun 常用命令速查清单(TypeScript 编译篇)
前端·javascript·typescript
anyup38 分钟前
uni-app 全能日历组件,支持农历、酒店预订、打卡签到、价格日历多种场景
前端·前端框架·uni-app
果然1231 小时前
Vue 3 Composition API 最佳实践:从项目实战中汲取的经验
前端
鱼人2 小时前
Web Components:未来的前端组件化标准?
前端