冰蓝科技
|
028-81705109
|
|
微信扫一扫
|

Spire.Cloud 纯前端文档控件

Spire.PDF 12.7.8 现已正式发布。该版本修复了转换 OFD 到 PDF 时出现 “OFD 解析失败”异常的问题,同时提升了 PDF 文档处理的稳定性。详情如下。

问题修复:


获取 Spire.PDF 12.7.8 请点击:

https://www.e-iceblue.cn/Downloads/Spire-PDF-NET.html

Spire.Presentation for Java 11.7.2 已发布。该版本支持转换 PPT 到纯 HTML 格式,并修复了两个在转换 PPT 到 PDF 时出现的问题。详情请查看以下内容。

新功能:

问题修复:


获取Spire.Presentation for Java 11.7.2请点击:

https://www.e-iceblue.cn/Downloads/Spire-Presentation-JAVA.html

Spire.XLS 16.7.0 现已正式发布。该版本成功修复了复制工作表时宏丢失、枚举类型单词拼写错误以及公式计算结果不正确的问题。更多详情如下。

问题修复:


获取 Spire.XLS for C++ 16.7.0 请点击:

https://www.e-iceblue.cn/Downloads/Spire-XLS-CPP.html

Spire.XLS for Python 16.7.1 现已发布。该版本新增支持数据模拟分析(方案管理器)、Slicer 切片器以及 Excel 转 JSON 数据功能,进一步扩展了数据分析与处理能力。详情如下。

新功能:


获取 Spire.XLS for Python 16.7.1 请点击:

https://www.e-iceblue.cn/Downloads/Spire-XLS-Python.html

PDF/A 是 ISO 标准化的长期归档格式,它将文档中的字体、色彩和元数据固化到统一的合规层级,确保文档在未来数十年内无论使用何种 PDF 阅读器都能完整重现。与之相对,普通 PDF 在日常编辑和内容提取上更加灵活。实际业务中通常需要在两种格式间灵活切换:合同归档时转为 PDF/A 以满足法规要求,审计复核时又需还原为普通 PDF 以提取文本内容。

Spire.PDF for JavaScript 基于 WebAssembly 在浏览器端直接完成 PDF 与 PDF/A 之间的双向转换,通过虚拟文件系统(VFS)管理输入输出文件,无需后端服务支持。

本文介绍两个核心功能点:

有关安装和项目配置,请参考 React 项目中集成 Spire.PDF for JavaScript。以下示例默认已安装 Spire.PDF 并完成 WebAssembly 模块初始化。


转换 PDF 到 PDF/A

PDF/A 归档转换的核心在于将普通 PDF 中的字体、色彩和元数据固化到符合 ISO 标准的层级。Spire.PDF 通过 PdfStandardsConverter 组件一键完成此操作,产品支持 PDF/A-1a、PDF/A-1b、PDF/A-2a、PDF/A-2b、PDF/A-3a、PDF/A-3b 等多个合规级别。

PdfStandardsConverter 支持的转换标准及其适用场景如下:

方法 标准 说明
ToPdfA1B PDF/A-1b 基于 PDF 1.4,仅保证视觉外观的可再现性,是最常用的归档级别
ToPdfA1A PDF/A-1a 在 1b 基础上要求文档标签与结构信息,支持无障碍阅读
ToPdfA2A PDF/A-2a 基于 PDF 1.7,要求标签与结构信息,支持图层和透明度
ToPdfA2B PDF/A-2b PDF/A-2 基本合规级别,允许透明度、图层和嵌入 OLE 对象
ToPdfA3A PDF/A-3a 在 2a 基础上允许嵌入 XML、Excel 等任意格式文件作为附件
ToPdfA3B PDF/A-3b PDF/A-3 基本合规级别,支持嵌入任意格式附件
ToPdfX1A2001 PDF/X-1a:2001 印刷交换标准,适合出版和打印工作流

以下以 PDF/A-2b 为例演示转换过程:

function App() {
  const convertToPDFA = async () => {
    // 获取 Spire.PDF WASM 模块
    const pdfModule = window.wasmModule?.spirepdf;

    // 检查模块是否就绪
    if (!pdfModule) {
      alert('Spire.PDF is not ready yet');
      return;
    }

    // 将字体和 PDF 文件载入 VFS
    await window.spire.FetchFileToVFS('arial.ttf', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = '电影介绍.pdf';
    await window.spire.FetchFileToVFS(inputFileName, "", `${process.env.PUBLIC_URL}/data/`);

    // 创建 PdfStandardsConverter
    let converter = new pdfModule.PdfStandardsConverter({ filePath: inputFileName });
    
    // 转换为 PDF/A-1b 格式
    const outputFileName = 'ToPDFA_result.pdf';
    converter.ToPdfA2B({ filePath: outputFileName });

    // // 转换为 PDF/A-1a
    // converter.ToPdfA1A({ filePath: outputFileName });

    // // 转换为 PDF/A-2a
    // converter.ToPdfA2A({ filePath: outputFileName });

    // // 转换为 PDF/A-2b
    // converter.ToPdfA2B({ filePath: outputFileName });

    // // 转换为 PDF/A-3a
    // converter.ToPdfA3A({ filePath: outputFileName });

    // // 转换为 PDF/A-3b
    // converter.ToPdfA3B({ filePath: outputFileName });

    // // 转换为 PDF/X-1a:2001
    // converter.ToPdfX1A2001({ filePath: outputFileName });

    // 从 VFS 读取转换后的文件,触发下载
    const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
    const blob = new Blob([fileArray], { type: 'application/pdf' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = outputFileName;
    a.click();
    URL.revokeObjectURL(url);

    // 释放资源
    converter.Dispose();
  };

  return (
    <div style={{ textAlign: 'center', height: '300px' }}>
      <h1>Convert PDF To PDF/A</h1>
      <button onClick={convertToPDFA}>
        Generate
      </button>
    </div>
  );
}

export default App;

通过 PdfStandardsConverter 转换后生成的 PDF/A 输出

通过 PdfStandardsConverter 转换后生成的 PDF/A 输出


转换 PDF/A 到 PDF

PDF/A 是长期归档的标准格式,但在日常编辑和内容提取场景中,可能需要将 PDF/A 还原为标准 PDF。Spire.PDF for JavaScript 通过加载 PDF/A 文档后逐页复制内容到新文档的方式实现这一反向转换,确保输出的标准 PDF 不保留 PDF/A 合规约束。

function App() {
  const convertToNormalPDF = async () => {
    // 获取 Spire.PDF WASM 模块
    const pdfModule = window.wasmModule?.spirepdf;

    // 检查模块是否就绪
    if (!pdfModule) {
      alert('Spire.PDF is not ready yet');
      return;
    }

    // 将字体和 PDF 文件载入 VFS
    await window.spire.FetchFileToVFS('arial.ttf', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'PDFA_JP.pdf';
    await window.spire.FetchFileToVFS(inputFileName, "", `${process.env.PUBLIC_URL}/data/`);

    // 创建 PdfDocument 对象
    let doc = new pdfModule.PdfDocument();
    doc.LoadFromFile(inputFileName);

    // 创建新的 PDF 文档用于在新文件上绘制内容
    let newDoc = new pdfModule.PdfNewDocument();
    newDoc.CompressionLevel = pdfModule.PdfCompressionLevel.None;

    // 遍历原始文档中的每一页
    for (let i = 0; i < doc.Pages.Count; i++) {
      let page = doc.Pages.get_Item(i);
      // 获取当前页面的大小
      let size = page.Size;

      // 向新文档添加相同大小且无边距的页面
      let newPage = newDoc.Pages.Add({ size: size, margins: new pdfModule.PdfMargins() });

      // 将原始页面的内容绘制到新页面上
      let template = page.CreateTemplate();
      let layoutWidget = new pdfModule.PdfLayoutWidget(template.H);
      layoutWidget.Draw({ page: newPage, x: 0, y: 0 });
      // page.CreateTemplate().Draw({page: newPage, x: 0, y: 0}); 
    }

    // 定义输出文件名
    const outputFileName = "PDFAToPdf_result.pdf";

    // 保存文档到指定路径
    newDoc.Save(outputFileName);

    // 从 VFS 读取生成的文件并触发下载
    const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
    const blob = new Blob([fileArray], { type: 'application/pdf' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = outputFileName;
    a.click();
    URL.revokeObjectURL(url);

    // 释放资源
    newDoc.Dispose();
    doc.Dispose();
  };

  return (
    <div style={{ textAlign: 'center', height: '300px' }}>
      <h1>Convert PDF/A To Normal PDF</h1>
      <button onClick={convertToNormalPDF}>
        Generate
      </button>
    </div>
  );
}

export default App;

通过创建新文档逐页复制内容生成的普通 PDF 输出

通过创建新文档逐页复制内容生成的普通 PDF 输出


常见问题

加密的 PDF 能否转换为 PDF/A

原因:需要输入密码才能打开的加密 PDF 无法直接被 PdfStandardsConverter 处理,需要在加载时提供密码。

解决:PdfStandardsConverter 方法支持传入 password 参数,转换带密码的 PDF 到 PDF/A:

// 创建 PdfStandardsConverter 时指定密码
let converter = new pdfModule.PdfStandardsConverter({ filePath: inputFileName, password: "password" });
converter.ToPdfA2A({ filePath: outputFileName });
converter.Dispose();

获取免费许可证

如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。

书签是 Word 文档中一种不可见的定位标记,它充当文档中的"坐标",能够精确标记某个位置或一段文本范围。但书签的真正价值不仅在于定位——通过编程手段获取书签范围内的内容、替换其中的占位文本、删除不再需要的内容,或在书签位置插入文本、段落、表格和图片,开发者可以实现合同模板的自动填充、报告数据的动态注入、表单内容的批量清理等高级文档处理流程。可以说,围绕着书签内容"读、写、删、插"的操作组合,构成了 Word 自动化的核心工作流。

Spire.Doc for JavaScript 基于 WebAssembly 在浏览器端直接完成书签内容的读取、替换、删除以及元素插入操作,通过虚拟文件系统(VFS)管理文件,无需后端服务支持。

本文介绍四个核心功能点:

有关安装和项目配置,请参考 React 项目中集成 Spire.Doc for JavaScript。以下示例默认已安装 Spire.Doc 并完成 WebAssembly 模块初始化。


获取书签内容

获取书签内容是对书签进行任何操作的前提。通过 BookmarksNavigator 定位到指定书签后,GetBookmarkContent 方法将书签范围内的内容作为 TextBodyPart 对象返回,开发者可以遍历其 BodyItems 集合下的元素进行获取。

function App() {
  const bookmarkContent = async () => {
    // 获取 Spire.Doc WASM 模块
    const docModule = window.wasmModule?.spiredoc;

    // 检查 WASM 模块是否已加载完成
    if (!docModule) {
      alert('Spire.Doc is not ready yet');
      return;
    }

    // 将 Word 文档载入虚拟文件系统(VFS)
    const inputFileName = '合同模板.docx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/data/`);

    // 加载 Word 文档
    const doc = new docModule.Document();
    doc.LoadFromFile(inputFileName);

    // 创建 BookmarksNavigator 并定位到书签
    let navigator = new docModule.BookmarksNavigator(doc);
    navigator.MoveToBookmark("合同书签");
    let textBodyPart = navigator.GetBookmarkContent();

    // 迭代书签内容中的元素,提取文本
    let text = "";
    for (let i = 0; i < textBodyPart.BodyItems.Count; i++) {
      let item = textBodyPart.BodyItems.get_Item(i);
      if (item instanceof docModule.Paragraph) {
        for (let j = 0; j < item.ChildObjects.Count; j++) {
          let childObject = item.ChildObjects.get_Item(j);
          if (childObject instanceof docModule.TextRange) {
            text += childObject.Text;
          }
        }
      }
    }

    // 保存为 .txt 文件
    const outputFileName = "获取的内容.txt";

    // TXT 文件保存到 VFS 并触发下载
    window.dotnetRuntime.Module.FS.writeFile(outputFileName, text);

    const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
    const blob = new Blob([fileArray], { type: 'text/plain' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = outputFileName;
    a.click();
    URL.revokeObjectURL(url);

    // 释放资源
    doc.Dispose();
  };

  return (
    <div style={{ textAlign: 'center', height: '300px' }}>
      <h1>Get Bookmark Content from Word Document</h1>
      <button onClick={bookmarkContent}>
        Generate
      </button>
    </div>
  );
}

export default App;

执行上述代码,将把书签"合同书签"范围内的文本内容提取并保存为独立的 .txt 文件:

查看提取的书签文本内容


替换书签内容

替换书签内容是在文档模板填充中最常用的操作。通过 BookmarksNavigator 定位到书签后,调用ReplaceBookmarkContent 方法不仅支持替换为纯文本,还支持替换为表格等复杂元素,适合在合同生成、报表填充等场景中替换占位符。

function App() {
  const replaceBookmarkContent = async () => {
    // 获取 Spire.Doc WASM 模块
    const docModule = window.wasmModule?.spiredoc;

    // 检查 WASM 模块是否已加载完成
    if (!docModule) {
      alert('Spire.Doc is not ready yet');
      return;
    }

    // 将字体和 Word 文件载入 VFS
    await window.spire.FetchFileToVFS('SIMSUN.TTC', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = '书签文档.docx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/data/`);

    // 加载 Word 文档
    const doc = new docModule.Document();
    doc.LoadFromFile(inputFileName);

    // 创建 BookmarksNavigator 并定位到书签
    let navigator = new docModule.BookmarksNavigator(doc);
    navigator.MoveToBookmark("书签1");

    // 替换“书签1”的内容——用文本替换
    navigator.ReplaceBookmarkContent({ text: "这是替换到书签的文本", saveFormatting: true });

    // 继续替换"书签2"的内容——用表格替换
    navigator.MoveToBookmark("书签2");

    // 创建表格
    let table = new docModule.Table(doc, true);
    table.ResetCells(4, 5);

    // 创建数据表并将数据填充到表格中
    let dt = [
      ["城市", "省份", "人口", "面积(km²)", "简称"],
      ["北京", "北京", "2189万", "16410", "京"],
      ["上海", "上海", "2475万", "6340", "沪"],
      ["广州", "广东", "1867万", "7434", "穗"]];
    for (let i = 0; i < 4; i++) {
      for (let j = 0; j < 5; j++) {
        table.Rows.get_Item(i).Cells.get_Item(j).AddParagraph().AppendText(dt[i][j]);
      }
    }

    // 创建 TextBodyPart 实例并将表格添加到其中
    let part = new docModule.TextBodyPart({ doc: doc });
    part.BodyItems.Add(table);

    // 用 TextBodyPart 对象替换当前书签内容
    navigator.ReplaceBookmarkContent({ bodyPart: part });

    // 保存为新的 .docx 文件
    const outputFileName = "替换书签.docx";
    doc.SaveToFile({ fileName: outputFileName, fileFormat: docModule.FileFormat.Docx2013 });

    // 从 VFS 读取生成的文件并触发下载
    const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
    const blob = new Blob([fileArray], { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = outputFileName;
    a.click();
    URL.revokeObjectURL(url);

    // 释放资源
    doc.Dispose();
  };

  return (
    <div style={{ textAlign: 'center', height: '300px' }}>
      <h1>Replace Bookmark Content in Word</h1>
      <button onClick={replaceBookmarkContent}>
        Generate
      </button>
    </div>
  );
}

export default App;

此方式可以替换书签内容为纯文本,也支持替换为表格等复杂元素。书签标记本身在替换后仍然保留,便于后续再次定位。执行效果如下图所示:

替换书签内容后生成的合同文档


删除书签内容

删除书签内容与删除书签标记是两个不同的操作。通过 BookmarksNavigator 定位到书签后,调用 DeleteBookmarkContent 方法可以移除书签范围内的文本内容,但保留书签标记本身,以便后续重新填入内容。如果只需清空内容而保留定位标记,此方法是首选。

function App() {
  const deleteBookmarkContent = async () => {
    // 获取 Spire.Doc WASM 模块
    const docModule = window.wasmModule?.spiredoc;

    // 检查 WASM 模块是否已加载完成
    if (!docModule) {
      alert('Spire.Doc is not ready yet');
      return;
    }

    // 将 Word 文件载入 VFS
    const inputFileName = '合同模板.docx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/data/`);

    // 加载 Word 文档
    const doc = new docModule.Document();
    doc.LoadFromFile(inputFileName);

    // 创建 BookmarksNavigator 并定位到书签
    let navigator = new docModule.BookmarksNavigator(doc);
    navigator.MoveToBookmark("合同书签");

    // 删除书签内容,保留书签标记
    navigator.DeleteBookmarkContent(true);

    // 保存为新的 .docx 文件
    const outputFileName = "删除书签内容.docx";

    doc.SaveToFile({ fileName: outputFileName, fileFormat: docModule.FileFormat.Docx2013 });

    // 从 VFS 读取生成的文件并触发下载
    const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
    const blob = new Blob([fileArray], { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = outputFileName;
    a.click();
    URL.revokeObjectURL(url);

    // 释放资源
    doc.Dispose();
  };

  return (
    <div style={{ textAlign: 'center', height: '300px' }}>
      <h1>Delete Bookmark Content in Word Document</h1>
      <button onClick={deleteBookmarkContent}>
        Generate
      </button>
    </div>
  );
}

export default App;

使用 DeleteBookmarkContent 删除的是书签范围内的文本内容,书签标记本身仍然保留;而 Bookmarks.Remove 移除的是书签标记,范围内的文本不受影响。

执行后文档中书签"合同书签"范围内的文本被移除,但书签标记仍保留在文档中:

删除书签内容后的文档效果——书签标记保留,内容被清空


在书签位置插入文本、段落、表格和图片

Spire.Doc 支持在书签位置灵活插入多种类型的文档元素。提供 InsertText、InsertParagraph、InsertTable 等方法插入文本、段落和表格。同时也可以根据书签起始节点在段落 ChildObjects 中的索引来插入多种元素。

function App() {
  const insertElementsAtBookmark = async () => {
    // 获取 Spire.Doc WASM 模块
    const docModule = window.wasmModule?.spiredoc;

    // 检查 WASM 模块是否已加载完成
    if (!docModule) {
      alert('Spire.Doc is not ready yet');
      return;
    }

    // 加载字体和 Word 文档到 VFS
    await window.spire.FetchFileToVFS('MSYH.TTC', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = '书签文档.docx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/data/`);

    // 创建 Document 对象并加载文档
    const doc = new docModule.Document();
    doc.LoadFromFile(inputFileName);

    // 定位到书签位置
    let navigator = new docModule.BookmarksNavigator(doc);
    navigator.MoveToBookmark("书签1");

    // 1. 插入文本
    navigator.InsertText("这是插入的文本内容。", true);

    // 2. 插入段落
    let newParagraph = new docModule.Paragraph(doc);
    newParagraph.AppendText("这是插入的段落内容。")
    navigator.MoveToBookmark("书签2");
    navigator.InsertParagraph(newParagraph);

    // 3. 插入表格 — 2 行 3 列
    let table = new docModule.Table(doc, true);
    table.ResetCells(2, 3);
    table.Rows.get_Item(0).Cells.get_Item(0).AddParagraph().AppendText("名称");
    table.Rows.get_Item(0).Cells.get_Item(1).AddParagraph().AppendText("数量");
    table.Rows.get_Item(0).Cells.get_Item(2).AddParagraph().AppendText("备注");
    table.Rows.get_Item(1).Cells.get_Item(0).AddParagraph().AppendText("产品 A");
    table.Rows.get_Item(1).Cells.get_Item(1).AddParagraph().AppendText("100");
    table.Rows.get_Item(1).Cells.get_Item(2).AddParagraph().AppendText("已入库");

    navigator.MoveToBookmark("书签3");
    navigator.InsertTable(table);

    // 4. 插入图片
    const imageFileName = '图片.png';
    await window.spire.FetchFileToVFS(imageFileName, '', `${process.env.PUBLIC_URL}/data/`);
    let picture = new docModule.DocPicture(doc);
    picture.LoadImage(imageFileName);
    picture.Width = 100;
    picture.Height = 200;

    navigator.MoveToBookmark("书签4");
    // 获取书签起始节点
    let start = navigator.CurrentBookmark.BookmarkStart;
    // 获取书签所在的段落
    let bookmarkPara = start.OwnerParagraph;
    // 获取书签起始节点在段落中的索引位置
    let startIndex = bookmarkPara.ChildObjects.IndexOf(start);
    // 在书签起始节点后插入图片
    bookmarkPara.ChildObjects.Insert(startIndex + 1, picture);

    // 保存文档为 .docx 格式
    const outputFileName = "插入元素到书签.docx";

    doc.SaveToFile({ fileName: outputFileName, fileFormat: docModule.FileFormat.Docx2013 });

    // 从 VFS 读取生成的文件并触发下载
    const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
    const blob = new Blob([fileArray], { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = outputFileName;
    a.click();
    URL.revokeObjectURL(url);

    // 释放 Document 资源
    doc.Dispose();
  };

  return (
    <div style={{ textAlign: 'center', height: '300px' }}>
      <h1>Insert Elements at Bookmark Position</h1>
      <button onClick={insertElementsAtBookmark}>
        Generate
      </button>
    </div>
  );
}

export default App;

执行上述代码,将在书签处插入文本、新段落、表格和图片,原有内容不会被覆盖:

在书签位置插入文本、段落、表格和图片的效果


常见问题

替换书签内容后,原来的字体、字号、颜色等格式丢了怎么办?

ReplaceBookmarkContent 默认会用纯文本替换,原格式会丢失。如果需要保留书签原有的格式,传入 saveFormatting: true:

navigator.ReplaceBookmarkContent({ text: "新内容", saveFormatting: true });

这样替换后的文本会沿用书签原来的字体、字号、颜色等格式。

如何批量处理文档中的多个书签?

遍历 doc.Bookmarks 集合,逐个定位并操作:

for (let i = 0; i < doc.Bookmarks.Count; i++) {
    let bookmark = doc.Bookmarks.get_Item(i);
    navigator.MoveToBookmark(bookmark.Name);
    // 执行替换、删除或插入操作
}

DeleteBookmarkContent 和直接删除书签标记有什么区别?

  • DeleteBookmarkContent:只清空书签范围内的内容,书签标记保留在文档中,后续仍可通过书签名称定位并填入新内容。
  • Bookmarks.Remove:移除书签标记本身,书签范围内的内容不受影响,但书签名称会消失,无法再定位。

两者互补,根据需求选择:需要保留"占位"能力就用 DeleteBookmarkContent,不需要书签了就移除标记。


获取免费许可证

如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。

书签相当于 Word 文档中看不见的"锚点",能准确定位到指定位置或选中文本。无论是合同模板中的待填写区域、长文档中需要跳转的关键章节,还是批量生成报表时用于定位数据插入点,书签都是背后关键的锚点。开发者可以基于书签实现文档内容的动态填充、定位导航、内容提取等高级功能,因此书签操作是 Word 自动化中最常用的基础能力之一。

Spire.Doc for JavaScript 基于 WebAssembly 在浏览器端直接完成书签的创建、定位和删除操作,通过虚拟文件系统(VFS)管理文件,无需后端服务支持。

本文介绍三个核心功能点:

有关安装和项目配置,请参考 React 项目中集成 Spire.Doc for JavaScript。以下示例默认已安装 Spire.Doc 并完成 WebAssembly 模块初始化。


为段落添加书签

在已有文档中追加书签,可以通过 AppendBookmarkStart 和 AppendBookmarkEnd 在指定段落上标记书签区域。不仅支持为文档中已有的段落添加书签标记,也支持在新段落中追加书签。Spire.Doc 同时支持嵌套书签,方便构建层级结构。

function App() {
  const createBookmarkInWord = async () => {
    // 获取 Spire.Doc WASM 模块
    const docModule = window.wasmModule?.spiredoc;

    // 检查模块是否就绪
    if (!docModule) {
      alert('Spire.Doc is not ready yet');
      return;
    }

    // 将 Word 文件载入 VFS
    const inputFileName = '中国旅行手册.docx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/data/`);

    // 加载文档
    const doc = new docModule.Document();
    doc.LoadFromFile(inputFileName);

    // 获取第一节,添加书签
    let section = doc.Sections.get_Item(0);

    AddBookmark(section);

    // 保存为 .docx 文件
    const outputFileName = "添加书签.docx";

    doc.SaveToFile({ fileName: outputFileName, fileFormat: docModule.FileFormat.Docx2013 });

    // 从 VFS 读取文件,触发下载
    const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
    const blob = new Blob([fileArray], { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = outputFileName;
    a.click();
    URL.revokeObjectURL(url);

    // 释放资源
    doc.Dispose();
  };

  function AddBookmark(section) {
    // 书签 1:给文档已有的段落添加书签
    let paraStart = section.Paragraphs.get_Item(1); 
    let paraEnd = section.Paragraphs.get_Item(3); 

    paraStart.AppendBookmarkStart("书签1");  
    paraEnd.AppendBookmarkEnd("书签1"); 

    // 书签 2:新增段落添加书签
    let paragraph = section.AddParagraph(); 
    paragraph.AppendBookmarkStart("书签2"); 
    paragraph.AppendText("这是新增段落。");
    paragraph.AppendBookmarkEnd("书签2"); 
  }

  return (
    <div style={{ textAlign: 'center', height: '300px' }}>
      <h1>Add Bookmark in Word</h1>
      <button onClick={createBookmarkInWord}>
        Generate
      </button>
    </div>
  );
}

export default App;

执行上述代码,添加的书签如下图所示:

在生成的 Word 文档中查看添加的书签


为所选文本添加书签

为已有段落中的特定文本添加书签,需要先通过 FindAllString 查找文本位置,使用 BookmarkStart 和 BookmarkEnd 构造函数创建书签对象,再通过 ChildObjects.Insert 将起始标记插入到匹配文本的 TextRange 之前,结束标记插入到其后。

function App() {
  const addBookmarkForMatchedText = async () => {
    // 获取 Spire.Doc WASM 模块
    const docModule = window.wasmModule?.spiredoc;

    // 检查 WASM 模块是否已加载完成
    if (!docModule) {
      alert('Spire.Doc is not ready yet');
      return;
    }

    // 将Word 文档载入虚拟文件系统(VFS)
    const inputFileName = '中国旅行手册.docx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/data/`);

    // 加载 Word 文档
    const doc = new docModule.Document();
    doc.LoadFromFile(inputFileName);

    // 查找文档中所有匹配"美食"的文本
    let textSelections = doc.FindAllString('美食', false, true);

    // 遍历每一处匹配结果,在其前后插入书签起始和结束标记
    for (let i = 0; i < textSelections.length; i++) {

      // 创建书签起始和结束对象(书签名称为 "书签_0"、"书签_1"...)
      let start = new docModule.BookmarkStart(doc, "书签_" + i);
      let end = new docModule.BookmarkEnd(doc, "书签_" + i);

      let selection = textSelections[i];

      // 获取匹配文本的 TextRange
      let textRange = selection.GetAsOneRange();

      // 获取匹配文本所在的段落
      let para = textRange.OwnerParagraph;

      // 获取该 TextRange 在段落子对象中的索引位置
      let index = para.ChildObjects.IndexOf(textRange);

      // 在 TextRange 之前插入书签起始,之后插入书签结束
      para.ChildObjects.Insert(index, start);
      para.ChildObjects.Insert(index + 2, end);
    }

    // 保存为新的 .docx 文件
    const outputFileName = "添加书签.docx";

    doc.SaveToFile({ fileName: outputFileName, fileFormat: docModule.FileFormat.Docx2013 });

    // 从VFS中读取生成的文件并触发下载
    const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
    const blob = new Blob([fileArray], { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = outputFileName;
    a.click();
    URL.revokeObjectURL(url);

    // 释放资源
    doc.Dispose();
  };

  return (
    <div style={{ textAlign: 'center', height: '300px' }}>
      <h1>Add Bookmarks for Specific Text in Word Documents</h1>
      <button onClick={addBookmarkForMatchedText}>
        Generate
      </button>
    </div>
  );
}

export default App;

此方式适用于需要在现有文档基础上添加定位标记的场景,例如在已写好的合同文档中标明待填充区域。执行上述代码,添加的书签如下图所示:

在生成的 Word 文档中查看添加的书签


删除书签

删除书签仅移除书签标记本身,书签范围内的文本内容会被保留。通过 document.Bookmarks 集合获取书签对象后,调用 Remove 方法即可完成删除。

function App() {
  const deleteBookmark = async () => {
    // 获取 Spire.Doc WASM 模块
    const docModule = window.wasmModule?.spiredoc;

    // 检查 WASM 模块是否已加载完成
    if (!docModule) {
      alert('Spire.Doc is not ready yet');
      return;
    }

    // 将Word 文档载入虚拟文件系统(VFS)
    const inputFileName = '添加书签.docx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/data/`);

    // 加载 Word 文档
    const doc = new docModule.Document();
    doc.LoadFromFile(inputFileName);

    // 按名称获取书签
    let bookmark = doc.Bookmarks.get_Item("书签_1");

    // // 按索引获取书签
    // let bookmark = doc.Bookmarks.get_Item(0);

    // 删除书签(不删除其内容)
    doc.Bookmarks.Remove(bookmark);

    // 保存为新的 .docx 文件
    const outputFileName = "删除书签.docx";

    doc.SaveToFile({ fileName: outputFileName, fileFormat: docModule.FileFormat.Docx2013 });

    // 从 VFS 读取生成的文件并触发下载
    const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
    const blob = new Blob([fileArray], { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = outputFileName;
    a.click();
    URL.revokeObjectURL(url);

    // 释放文档资源
    doc.Dispose();
  };

  return (
    <div style={{ textAlign: 'center', height: '300px' }}>
      <h1>Delete Bookmark by Name in Word Document</h1>
      <button onClick={deleteBookmark}>
        Generate
      </button>
    </div>
  );
}

export default App;

删除书签后,文档中原书签标记消失,但标记范围内的文本仍保留在文档中。

删除书签标记后的文档效果


常见问题

添加书签时提示名称重复

原因:Word 文档中书签名称必须唯一,重复添加同名书签会导致错误。

解决:在添加书签前检查名称是否已存在:

if (document.Bookmarks.FindByName("MyBookmark") === null) {
    paragraph.AppendBookmarkStart("MyBookmark");
    paragraph.AppendText("内容");
    paragraph.AppendBookmarkEnd("MyBookmark");
}

删除书签和删除书签内容有什么区别

原因:Spire.Doc 的 Bookmarks.Remove 仅移除书签标记(开始和结束标记),中间的文本内容不受影响。

解决:根据实际需求选择操作:

// 仅删除书签标记,保留文本
document.Bookmarks.Remove(bookmark);

// 删除书签及其内容(通过 BookmarksNavigator 定位后删除)
let navigator = new docModule.BookmarksNavigator(doc);
navigator.MoveToBookmark("MyBookmark");
navigator.navigator.DeleteBookmarkContent(true); // 删除书签范围内的内容

AppendBookmarkStart 和 AppendBookmarkEnd 必须在同一段落吗

原因:起始标记和结束标记可以在不同段落,代码中"书签1"的示例展示了跨段落的用法。关键限制在于书签范围内的文档对象结构必须完整,不能跨表格单元格标记,因为单元格是独立容器,跨单元格可能导致书签识别异常。

解决:如果书签范围跨越了表格单元格,应调整书签的起始或结束位置,确保在同一单元格内闭合。


获取免费许可证

如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。

在 Java 中编辑 PDF 文档

在许多 Java 应用程序中,处理 PDF 文件是一项常见需求——无论是生成发票、修改合同,还是为报告添加批注,都经常需要对 PDF 文档进行操作。虽然 PDF 格式因其稳定性和跨平台特性,成为文档共享的常用格式,但如果没有合适的开发库,直接通过代码编辑 PDF 文件可能会比较复杂。

本教程将介绍如何使用 Spire.PDF for Java(一个功能全面且易于使用的 PDF 开发 API)对 PDF 文件中的内容进行添加、替换、删除和安全保护操作。我们将通过示例详细讲解如何添加页面、文本、图像、表格、注释,如何替换内容、删除元素,以及如何使用水印和密码保护文件。

为什么选择 Spire.PDF 在 Java 编辑 PDF 文件

Spire.PDF 提供了一套完整的 PDF 处理功能,非常适合需要在 Java 应用程序中操作 PDF 文件的开发人员。以下是选择 Spire.PDF 的几个主要原因:

  • 易于使用:API 直观易懂,只需少量代码即可完成复杂操作。
  • 功能丰富:Spire.PDF 支持多种功能,包括文本和图像处理、页面管理以及安全功能。
  • 高性能:该库经过性能优化,即使是大型 PDF 文件也能快速处理。
  • 无外部依赖:Spire.PDF 是一个独立运行的类库,无需在项目中额外添加其他依赖组件。

借助 Spire.PDF,开发人员可以轻松处理 PDF 文件,而无需深入了解 PDF 格式本身的复杂结构。

配置 Java 开发环境

安装 Spire.PDF for Java

开始使用 Spire.PDF 前,首先需要将其添加到 Java 项目中。您可以从其官方网站下载该库,或通过 Maven 引入:

Maven 用户配置方式:

<repositories>
    <repository>
        <id>com.e-iceblue</id>
        <name>e-iceblue</name>
        <url>https://repo.e-iceblue.cn/repository/maven-public/</url>
    </repository>
</repositories>
<dependencies>
    <dependency>
        <groupId>e-iceblue</groupId>
        <artifactId>spire.pdf</artifactId>
        <version>12.6.4</version>
    </dependency>
</dependencies>

手动配置方式:

从官方网站下载 Spire.PDF for Java,并将 JAR 文件添加到项目的 classpath 中。

初始化并加载 PDF 文档

完成类库配置后,就可以开始加载 PDF 文件。操作如下:

PdfDocument doc = new PdfDocument();
doc.loadFromFile("sample.pdf");

此代码创建了一个新的 PdfDocument 对象,并通过指定路径加载 PDF 文件。通过调用 loadFromFile,PDF 文档将被加载到内存中,之后即可进行进一步编辑操作。

在 Java 中向 PDF 文件添加内容

使用 Spire.PDF for Java,可以轻松向现有 PDF 文档中添加各种内容,例如新页面、文本、图片、表格以及批注等。

添加新页面

向现有 PDF 文档添加新页面非常简单。示例代码如下:

// 添加新页面
PdfPageBase new_page = doc.getPages().add(PdfPageSize.A4, new PdfMargins(54));
// 在页面上绘制文本或进行其他操作
new_page.getCanvas().drawString("这是一个新添加的页面。", new PdfTrueTypeFont(new Font("Times New Roman",Font.PLAIN,18)), PdfBrushes.getBlue(), 0, 0);

在上述代码中,我们使用 add 方法创建了一个 A4 大小并带有指定边距的新页面。然后,我们使用指定的字体和颜色在新页面上绘制字符串。drawString 方法将文本放置在页面的左上角,让您能够快速添加内容。

向 PDF 文件添加文本

要将文本插入到现有页面的特定区域,请使用以下代码:

// 获取特定页面
PdfPageBase page = doc.getPages().get(0);
// 定义一个用于放置文本的矩形区域
Rectangle2D.Float rect = new Rectangle2D.Float(54, 300, (float) page.getActualSize().getWidth() - 108, 100);
// 创建画刷和字体
PdfSolidBrush brush = new PdfSolidB
rush(new PdfRGBColor(Color.BLUE));
PdfTrueTypeFont font = new PdfTrueTypeFont(new Font("Microsoft YaHei", Font.PLAIN,18));
// 在页面的指定区域绘制文本
page.getCanvas().drawString("此行由 Spire.PDF for Java 创建。",font, brush, rect);

该代码获取文档的第一页,并定义了一个用于放置文本的矩形。Rectangle2D.Float 类允许您指定文本定位的精确尺寸。然后,我们使用 drawString 方法,用蓝色画刷和自定义字体绘制指定文本,确保文本在定义区域内渲染。

在 Java 中向 PDF 添加文本

向 PDF 文件添加图像

插入图像到 PDF 也同样简单:

// 获取特定页面
PdfPageBase page = doc.getPages().get(0);
// 加载图像
PdfImage image = PdfImage.fromFile("logo.png");
// 指定添加图像的坐标
float x = 54;
float y = 300;
// 在页面的指定坐标处绘制图像
page.getCanvas().drawImage(image, x, y);

这里,我们从指定文件路径加载图像,并在第一页的定义坐标 (x, y) 处绘制它。drawImage 方法允许您精确地定位图像,方便将视觉元素融入文档中。

在 Java 中向 PDF 添加图像

向 PDF 文件添加表格

Spire.PDF 也支持向 PDF 文档中插入表格:

// 获取特定页面
PdfPageBase page = doc.getPages().get(0);
// 创建表格
PdfTable table = new PdfTable();
// 定义表格数据
String[][] data = {
        new String[]{"姓名", "年龄", "国家"},
        new String[]{"Alice", "25", "美国"},
        new String[]{"Bob", "30", "英国"},
        new String[]{"Charlie", "28", "加拿大"}
};
// 将数据分配给表格
table.setDataSource(data);
// 设置表格样式
PdfTableStyle style = new PdfTableStyle();
style.getDefaultStyle().setFont(new PdfTrueTypeFont(new Font("Arial", Font.PLAIN, 12)));
table.setStyle(style);
// 在页面上绘制表格
table.draw(page, new Point2D.Float(50, 80));

在此示例中,我们创建了一个表格,并使用二维数组定义其数据源。分配数据后,我们使用 PdfTableStyle 为表格设置样式,这允许您自定义字体和表格外观。最后,我们使用 draw 方法在指定坐标处渲染第一页的表格。

添加注释或批注

PDF 批注可以增强文档的交互性,例如添加备注、评论或提示信息。实例代码如下:

// 获取特定页面
PdfPageBase page = doc.getPages().get(0);
// 创建自由文本注释
PdfPopupAnnotation popupAnnotation = new PdfPopupAnnotation();
popupAnnotation.setLocation(new Point2D.Double(90, 260));
// 设置注释的内容
popupAnnotation.setText("这是一个由 Spire.PDF for Java 添加的弹出式注释。");
// 设置注释的图标和颜色
popupAnnotation.setIcon(PdfPopupIcon.Comment);
popupAnnotation.setColor(new PdfRGBColor(Color.RED));
// 将注释添加到注释集合中
page.getAnnotations().add(popupAnnotation);

此代码段在页面上的指定位置创建一个弹出式注释。通过调用 setLocation,定义注释出现的位置。setText 方法允许您指定注释中显示的内容,同时您可以自定义批注的图标和颜色。最后,该注释被添加到页面的注释集合中。

在 Java 中向 PDF 添加注释

您可能还喜欢:在 Java 中向 PDF 文档添加页码

在 Java 中替换 PDF 文件中的内容

除了向 PDF 文件添加内容之外,开发人员还经常需要修改已有内容,例如替换文本或更新图片。

使用 Spire.PDF for Java,可以方便地对 PDF 文档中的文本和图片进行替换操作。

替换 PDF 文件中的文本

要替换 PDF 中的现有文本,可以使用以下代码:

// 创建 PdfTextReplaceOptions 对象
PdfTextReplaceOptions textReplaceOptions = new PdfTextReplaceOptions();
// 指定文本替换选项
textReplaceOptions.setReplaceType(EnumSet.of(ReplaceActionType.IgnoreCase));
// 遍历页面
for (int i = 0; i < doc.getPages().getCount(); i++) {
    // 获取特定页面
    PdfPageBase page = doc.getPages().get(i);
    // 基于页面创建 PdfTextReplacer 对象
    PdfTextReplacer textReplacer = new PdfTextReplacer(page);
    // 设置替换选项
    textReplacer.setOptions(textReplaceOptions);
    // 将所有匹配的目标文本替换为新文本
    textReplacer.replaceAllText("PDF", "OFD");
}

在此示例中,我们创建了一个 PdfTextReplaceOptions 对象用于设置文本替换规则,例如忽略大小写。然后,通过循环遍历 PDF 文档中的所有页面,并为每一页创建一个 PdfTextReplacer 对象。最后,调用 replaceAllText 方法,以将所有出现的 "PDF" 替换为 "OFD"。

在 Java 中替换 PDF 中的文本

替换 PDF 文件中的图像

替换图像遵循类似的模式:

// 获取特定页面
PdfPageBase page = doc.getPages().get(0);
// 加载图像
PdfImage image = PdfImage.fromFile("logo.png");
// 从页面获取图像信息
PdfImageHelper imageHelper = new PdfImageHelper();
PdfImageInfo[] imageInfo = imageHelper.getImagesInfo(page);
// 替换图像
imageHelper.replaceImage(imageInfo[0], image);

此代码使用 PdfImageHelper 类从指定页面检索图像信息。从文件加载新图像后,调用 replaceImage 将页面上第一个图像替换为新图像。

在 Java 中替换 PDF 中的图像

您可能还喜欢:Java 在 PDF 中应用不同的字体

在 Java 中移除 PDF 文件中的内容

除了添加和替换内容之外,删除 PDF 中不需要的元素也是常见需求。

从 PDF 文件中移除页面

要从 PDF 中移除整个页面,请使用以下代码:

// 移除特定页面
doc.getPages().removeAt(0);

这个简单的命令移除了文档的第一页。通过调用 removeAt,可以指定要移除页面的索引,从而简化 PDF 中的页面管理。

从 PDF 文件中删除图像

要从页面中移除图像:

// 获取特定页面
PdfPageBase page = pdf.getPages().get(0);
// 从页面获取图像信息
PdfImageHelper imageHelper = new PdfImageHelper();
PdfImageInfo[] imageInfos = imageHelper.getImagesInfo(page);
// 删除页面上指定的图像
imageHelper.deleteImage(imageInfos[0]);

此代码检索首页的所有图像,并使用 PdfImageHelper 的 deleteImage 方法删除第一个图像。

删除注释

移除注释也同样简单:

// 获取特定页面
PdfPageBase page = pdf.getPages().get(0);
// 移除指定的注释
page.getAnnotationsWidget().removeAt(0);

此代码段会删除指定页面中的第一个注释。removeAt 方法用于指定需要删除的批注索引,可以帮助开发人员快速清理 PDF 中不需要的评论或标记。

删除附件

如果 PDF 文件中包含附件,也可以通过以下方式删除:

// 获取附件集合
PdfAttachmentCollection attachments = doc.getAttachments();
// 移除特定附件
attachments.removeAt(0);

此代码检索文档的附件集合并使用 removeAt 方法移除第一个附件。

在 Java 中保护 PDF 文件

Spire.PDF for Java 提供了完善的安全功能,可以帮助开发人员轻松实现 PDF 文件保护。

在 PDF 文件上应用水印

水印常用于品牌展示、版权保护或防止文档被未经授权复制。以下代码展示了如何为 PDF 文件添加文本水印:

// 创建字体和画刷
PdfTrueTypeFont font = new PdfTrueTypeFont(new Font("Arial Black", Font.PLAIN, 50), true);
PdfBrush brush = PdfBrushes.getBlue();
// 指定水印文本
String watermarkText = "严禁复制";
// 指定不透明度级别
float opacity = 0.6f;
// 遍历页面
for (int i = 0; i < doc.getPages().getCount(); i++) {
    PdfPageBase page = doc.getPages().get(i);    
    // 设置水印的透明度级别
    page.getCanvas().setTransparency(opacity);
    // 测量水印文本的尺寸
    Dimension2D textSize = font.measureString(watermarkText);
    // 获取页面的宽度和高度
    double pageWidth = page.getActualSize().getWidth();
    double pageHeight = page.getActualSize().getHeight();
    // 计算将水印置于页面中心的位置
    double x = (pageWidth - textSize.getWidth()) / 2;
    double y = (pageHeight - textSize.getHeight()) / 2;
    // 在页面上计算出的位置绘制水印文本
    page.getCanvas().drawString(watermarkText, font, brush, x, y);
}

此代码配置文本水印的外观,并使用 drawString 方法将其放置在 PDF 文件每一页的中心,有效地阻止未经授权的复制。

用密码保护 PDF 文件

如果需要限制用户访问 PDF 文件,可以为文档设置密码保护。

// 指定用户密码和所有者密码
String userPassword = "open_psd";
String ownerPassword = "permission_psd";
// 使用两个密码创建 PdfSecurityPolicy 对象
PdfSecurityPolicy securityPolicy = new PdfPasswordSecurityPolicy(userPassword, ownerPassword);
// 设置加密算法
securityPolicy.setEncryptionAlgorithm(PdfEncryptionAlgorithm.AES_256);
// 设置文档权限(如果不设置,则默认为全部禁止)
securityPolicy.setDocumentPrivilege(PdfDocumentPrivilege.getAllowAll());
// 限制编辑
securityPolicy.getDocumentPrivilege().setAllowModifyContents(false);
securityPolicy.getDocumentPrivilege().setAllowCopyContentAccessibility(false);
securityPolicy.getDocumentPrivilege().setAllowContentCopying(false);
// 加密 PDF 文件
doc.encrypt(securityPolicy);

该代码通过定义用户密码(用于打开)和所有者密码(用于编辑、打印等权限),为 PDF 文档添加密码保护和加密功能。PdfSecurityPolicy 对象管理安全设置,包括 AES-256 加密算法和权限级别。最后,doc.encrypt(securityPolicy) 加密文档,确保只有授权用户才能访问或修改它。

在 Java 中保护 PDF文件

您可能还喜欢:如何在 Java 中为 PDF 添加数字签名

结论

在 Java 中编辑 PDF 文件常被视为一项复杂的任务,但借助 Spire.PDF for Java,这一过程可以变得简单、高效。该库为开发者提供了灵活的 PDF 操作能力,可以通过清晰易懂的 API 来创建、修改、替换和保护 PDF 内容。从添加页面和图像到加密敏感文档,Spire.PDF 简化了工作流程中的每一步,同时保持专业的输出质量。

除了基础的 PDF 编辑功能之外,Spire.PDF 还支持自动化处理和企业级应用场景。无论您是将 PDF 处理集成到文档管理系统中,还是生成定制化报告,该库都能为长期项目提供稳定、可扩展的技术基础。凭借其全面的功能集和强大的性能,Spire.PDF for Java 是寻求对 PDF 文档进行精确、高效和可控操作的开发者的可靠选择。

Java 编辑 PDF 常见问题解答

问题1:在 Java 中编辑 PDF 的最佳库是什么?

答:Spire.PDF for Java 是全球开发者中的热门选择,它为有效的 PDF 处理提供了全面的功能。

问题2:可以使用 Java 编辑 PDF 中的现有文本吗?

答:可以。通过 Spire.PDF for Java,您可以使用 PdfTextReplacer 等类来替换或修改现有文本,并可自定义大小写敏感度和匹配行为选项。

问题3:如何在 Java 中插入或替换 PDF 中的图像?

答:在 Spire.PDF for Java 中,可以使用 drawImage() 插入图像,并使用 PdfImageHelper.replaceImage() 替换特定页面上的现有图像。

问题4:可以在 Java 中为 PDF 文件添加注释吗?

答:可以。使用 Spire.PDF for Java 提供的相应注释类,可以添加诸如高亮、评论和图章等注释。

问题5:可以从现有 PDF 文件中提取文本和图像吗?

答:可以。Spire.PDF for Java 提供了轻松提取 PDF 中文本、图像和其他元素的方法。有关详细说明和代码示例,请参阅:如何在 Java 中读取 PDF:提取文本、图像及更多内容

获取免费许可证

要充分体验 Spire.PDF for Java 的功能而不受任何评估限制,您可以申请 30 天免费试用许可证。

我们很高兴地宣布 Spire.PDF for Python 12.7.0 已发布。此版本新增了 AutoFontSize 属性,可自动调整文本大小以适应签名域。此外,还修复了替换文本时出现的字体问题。详细信息如下。

新功能:

问题修复:


获取 Spire.PDF for Python 12.7.0请点击:

https://www.e-iceblue.cn/Downloads/Spire-PDF-Python.html

Spire.Presentation for C++ 11.7.0 现已正式发布。该版本修复了拆分 PowerPoint 文档后,结果文档变大的问题、转换及加载过程中存在的问题,进一步提升了文档处理的稳定性。详情如下。

问题修复:


获取 Spire.Presentation for C++ 11.7.0 请点击:

https://www.e-iceblue.cn/Downloads/Spire-Presentation-CPP.html