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

相关推荐
禅思院2 小时前
前端部署“三层漏斗”完全指南:从CI/CD到自动回滚的工程化实战【开题】
前端·架构·前端框架
快乐肚皮2 小时前
深入理解Loop Engineering
前端·后端
风骏时光牛马2 小时前
VHDL十大经典基础功能设计实例代码合集
前端
小兔崽子去哪了3 小时前
Vue3 + Pinia 集成 IGV.js 实现 BAM 文件在线浏览
javascript·vue.js·后端
hunterandroid3 小时前
Notification 通知:从基础到渠道适配
前端
孟陬3 小时前
Claude Code 巧思 `Ctrl+S` 暂存键
前端·后端
PedroQue993 小时前
V1.6.1性能优化:高频路径提速与代码精简
前端·uni-app
猩猩程序员3 小时前
将 LiteLLM 迁移到 Rust —— 构建最快、最轻量的 AI Gateway
前端
lichenyang4533 小时前
JSBridge 分发升级:为什么要从 if-else 变成 Registry > 这是「ASCF 架构升级」系列的第 3 篇
前端
码上天下3 小时前
流式响应断了,前端怎么自动重连续传
前端