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

Spire.Cloud 纯前端文档控件

Spire.Presentation 11.3.1 现已正式发布。该版本优化了 PowerPoint 到 PDF 的转换功能。同时,一些在获取形状阴影效果、加载 3D 动画以及转换文档时出现的问题也得以成功被修复。更多详情如下。

问题修复:


获取Spire.Presentation 11.3.1,请点击:

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

我们很高兴地宣布发布 Spire.Doc for .NET 14.3.5。本次发布支持 Word 到 Excel 的转换,能够将 Word 内容直接导出为 Excel 电子表格。此外,与导出相关的类已重新组织到更清晰的命名空间结构中,以提高 API 的可读性。更多详细信息如下。

新功能:

调整:


获取Spire.Doc 14.3.5,请点击:

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

Spire.PDF 12.3.7 现已发布。本版本增强了 PDF 转 Word 和图片的转换功能,同时修复了多个问题,例如合并 PDF 时程序抛出 “System.OutOfMemoryException” 异常的问题,以及转换 PDF 到 Word 时内容格式不正确的问题。更多详情如下。

问题修复:


获取 Spire.PDF 12.3.7 请点击:

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

在 C++ 中将 PDF 转换为 OFD

OFD (Open Fixed-layout Document) 是电子公文出版版式内容的国家标准,在国内广泛应用于电子发票、政府采购和官方文档存档等。对于 C++ 开发者而言,快速转换 PDF 为 OFD 文件是一项常见的开发需求。

本教程将演示如何使用 Spire.PDF for C++ 库来自动化处理这个任务,主要从三个角度进行介绍,包括:转换单个 PDF 文档为 OFD、提取 PDF 页面转换以及批量转换多个文件。通过这些示例,你可以用 C++ 代码轻松在应用程序中集成 PDF 转 OFD 的功能。

在 C++ 中将单个 PDF 转换为 OFD

将整个 PDF 文件转换为 OFD 是最常见,也是最基础的操作。在 Spire.PDF for C++ 的帮助下,该任务仅需三个核心步骤就能轻松完成:初始化文档、加载 PDF 源文件、导出为 OFD。下面为具体的步骤介绍:

核心步骤:

  • 创建 PdfDocument 实例。
  • 使用 PdfDocument->LoadFromFile() 方法加载 PDF。
  • 使用 PdfDocument->SaveToFile(filename, FileFormat::OFD) 方法将 PDF 保存为 OFD 格式。

代码示例:

#include "Spire.Pdf.o.h"

using namespace Spire::Pdf;

int main()
{
    // 创建 PdfDocument 实例
    PdfDocument* pdf = new PdfDocument();

    // 加载 PDF 源文件
    pdf->LoadFromFile(L"/input/示例文档.pdf");

    // 将 PDF 保存为 OFD 文档
    pdf->SaveToFile(L"/output/转OFD.ofd", FileFormat::OFD);

    // 释放资源
    pdf->Close();
    delete pdf;

    return 0;
}

下面是 PDF 源文档与转换后的 OFD 文档对比图:

将单个 PDF 文件直接转换为 OFD

除了 OFD 转换,Spire.PDF 还支持将 PDF 转换为 Word 或 Excel,帮助你在不同办公需求间快速切换。

通过 C++ 转换特定 PDF 页面为 OFD

在实际应用时,你可能只需要转换 PDF 的一部分,例如只提取发票页或报告的特定章节。这不仅能减小文件体积,还能确保输出的 OFD 仅包含业务相关数据,无需对结果文档再进行编辑。

核心步骤:

  • 初始化两个 PdfDocument 实例,并使用 PdfDocument->LoadFromFile() 方法加载 PDF 源文档。
  • 遍历指定的 PDF 页面。
  • 在新文档中创建页面,并使用 CreateTemplate()->Draw() 方法将源页面内容绘制到新页面上。
  • 使用 PdfDocument->SaveToFile(filename, FileFormat::OFD) 方法将新的 PDF 文档保存为 OFD。

代码示例(提取第 2 至第 3 页):

#include "Spire.Pdf.o.h"
#include <iostream>

using namespace Spire::Pdf;

int main()
{
    // 创建 PdfDocument 实例并加载 PDF
    intrusive_ptr<PdfDocument> oldPdf = new PdfDocument();
    oldPdf->LoadFromFile(L"/input/示例文档.pdf");

    // 创建新的 PdfDocument 对象用于存放提取的页面
    intrusive_ptr<PdfDocument> newPdf = new PdfDocument();

    // 获取源文件总页数
    int pageCount = oldPdf->GetPages()->GetCount();
    std::cout << "总页数: " << pageCount << std::endl;

    // 提取第 2 页到第 3 页
    if (pageCount >= 3)
    {
        for (int i = 1; i <= 2; i++)
        {
            // 在目标文档中创建相同尺寸的新页面
            intrusive_ptr<PdfMargins> margins = new PdfMargins(0);
            intrusive_ptr<PdfPageBase> newPage = newPdf->GetPages()->Add(oldPdf->GetPages()->GetItem(i)->GetSize(), margins);

            // 基于源页面创建模板,并将其绘制到新页面上
            oldPdf->GetPages()->GetItem(i)->CreateTemplate()->Draw(newPage, new PointF(0, 0));
        }

        // 将提取后的结果保存为 OFD
        newPdf->SaveToFile(L"E:/Administrator/Python1/output/页面转OFD.ofd", FileFormat::OFD);
        std::cout << "指定范围页面已成功转换并保存为 OFD。" << std::endl;
    }

    // 关闭文档
    newPdf->Close();
    oldPdf->Close();

    return 0;
}

将 PDF 中的第二页到第三页转换为 OFD

推荐阅读:在 C++ 中将图像转换为 OFD(PNG、JPG、BMP)

批量转换多个 PDF 文件为 OFD

在处理大规模历史档案或云存储同步时,手动逐个转换 PDF 文件效率低下。对于多文件的业务流,例如迁移历史存档或同步云端目录等来说,实现多个 PDF 文档的批量自动化转换是一项核心需求。

通过利用 Spire.PDF 库,我们可以构建一套实用的解决方案,自动检测并转换目标文件夹下的所有 PDF 文件,从而节省人力成本。

核心步骤:

  • 定义输入和输出目录路径。
  • 创建 PdfDocument 类的对象。
  • 遍历文件夹中的所有 PDF 文件。
  • 通过 PdfDocument->SaveToFile(filename, FileFormat::OFD) 方法,将每一个 PDF 文件转换为 OFD。

代码示例:

#include "Spire.Pdf.o.h"
#include <iostream>
#include <filesystem>
#include <string>

namespace fs = std::filesystem;
using namespace Spire::Pdf;

int main()
{
    // 定义输入和输出目录
    std::string inputDir = "/input/pdf/";
    std::string outputDir = "/output/pdftoofd/";

    // 创建 PdfDocument 实例
    intrusive_ptr<PdfDocument> pdf = new PdfDocument();

    // 遍历输入目录
    for (const auto& entry : fs::directory_iterator(inputDir))
    {
        // 仅处理 .pdf 文件
        if (entry.path().extension() == ".pdf")
        {
            // 获取当前文件路径
            std::wstring inputPath = entry.path().wstring();

            // 构造输出文件名
            std::wstring outputFileName = entry.path().stem().wstring() + L".ofd";
            std::wstring outputPath = fs::path(outputDir).wstring() + outputFileName;

            // 加载并转换
            pdf->LoadFromFile(inputPath.c_str());
            pdf->SaveToFile(outputPath.c_str(), FileFormat::OFD);

            std::wcout << L"转换完成: " << outputFileName << std::endl;
        }
    }

    pdf->Close();
    std::cout << "批量转换任务已全部完成。" << std::endl;
    return 0;
}

C++ 批量将多个 PDF 转换为 OFD

在掌握了批量转换技术后,你还可以通过学习如何在 C++ 中将多个 PDF 文件合并为一个 PDF,来进一步优化文档处理流程。

常见问题解答

Q: OFD 格式是否能完美还原 PDF 的所有元素?

A: 是的,通过 Spire.PDF 进行的转换能够很好地保留文本、矢量图形和图像。其内部绘图逻辑能做到将 PDF 的布局和视觉完整性准确映射到 OFD 标准中。

Q: 转换过程如何处理 PDF 中的高分辨率图片?

A: 转换引擎会保留原始 PDF 图像的 DPI 和压缩设置。即使是批量处理,输出的 OFD 文件也能在保持高质量渲染的同时避免文件体积异常变大。

Q: PDF 表单或交互式元素能否转换?

A: OFD 主要是一种用于查看和打印的固定布局格式。在转换过程中,交互式表单字段一般会被扁平化为可视化图层,以确保数据在 OFD 文档中清晰可见,其交互性在 OFD 中将不再被激活。

结语

Spire.PDF for C++ 为处理 OFD 转换提供了灵活且强大的 API。无论是简单的格式转换,还是复杂的页面提取与批量自动化流,该库都能确保稳定且完整的输出。

如果你对 Spire.PDF 库感兴趣,欢迎该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。申请 30 天免费临时授权,在无限制的环境下深度体验该库的所有功能!

PDF 属性是提供有关 PDF 文件的附加信息的元数据。通常,这些属性包括但不限于文档的标题、作者、关键字、主题和创建文档的应用程序。在处理大量的 PDF 文件时,添加属性是必不可少的,因为它可以提升文件的可检索性。在本文中,您将学习如何使用 Spire.PDF for .NET 以编程方式设置或获取 PDF 属性。

安装 Spire.XLS for .NET

首先,您需要将 Spire.XLS for .NET 包含的 DLL 文件作为引用添加到您的 .NET 项目中。DLL 文件可以从此链接下载,也可以通过 NuGet 安装。

PM> Install-Package Spire.XLS

在 C#/VB.NET 中设置 PDF 文件的属性

基本的 PDF 文档属性,如标题、作者、主题和关键字,使用户以后更容易搜索或检索特定文档。以下是如何使用 Spire.PDF for .NET 设置这些属性的详细步骤。

  • C#
  • VB.NET
using Spire.Pdf;

namespace PDFProperties
{
    class Properties
    {
        static void Main(string[] args)
        {
            //创建一个PdfDocument实例
            PdfDocument pdf = new PdfDocument();

            //加载PDF文件
            pdf.LoadFromFile("示例文档.pdf");

            //设置标题
            pdf.DocumentInformation.Title = "PDF (可移植文档格式)";

            //设置作者
            pdf.DocumentInformation.Author = "冰蓝科技";

            //设置主题
            pdf.DocumentInformation.Subject = "设置PDF属性";

            //设置关键字
            pdf.DocumentInformation.Keywords = ".NET PDF, 属性, 文档";

            //设置生成器名称
            pdf.DocumentInformation.Producer = "Spire.PDF";

            //保存结果文档
            pdf.SaveToFile("Pdf属性.pdf");
            pdf.Dispose();
        }
    }
}
Imports Spire.Pdf

Namespace PDFProperties
    Friend Class Properties
        Private Shared Sub Main(ByVal args As String())
            '创建一个PdfDocument实例
            Dim pdf As PdfDocument = New PdfDocument()

            '加载PDF文件
            pdf.LoadFromFile("示例文档.pdf")

            '设置标题
            pdf.DocumentInformation.Title = "PDF (可移植文档格式)"

            '设置作者
            pdf.DocumentInformation.Author = "冰蓝科技"

            '设置主题
            pdf.DocumentInformation.Subject = "设置PDF属性"

            '设置关键字
            pdf.DocumentInformation.Keywords = ".NET PDF, 属性, 文档"

            '设置生成器名称
            pdf.DocumentInformation.Producer = "Spire.PDF"

            '保存结果文档
            pdf.SaveToFile("Pdf属性.pdf")
            pdf.Dispose()
        End Sub
    End Class
End Namespace

C#/VB.NET 设置或获取 PDF 属性

在 C#/VB.NET 中获取 PDF 文件的属性

要获取特定的 PDF 属性,可以使用 PdfDocumentInformation 类下的相应属性。以下是详细的步骤。

  • C#
  • VB.NET
using Spire.Pdf;
using System.IO;
using System.Text;

namespace GetPdfProperties

{
    class Program
    {
        static void Main(string[] args)
        {
            //创建一个PdfDocument实例
            PdfDocument pdf = new PdfDocument();

            //加载PDF文件
            pdf.LoadFromFile("Pdf属性.pdf");

            //创建StringBuilder实例
            StringBuilder content = new StringBuilder();

            //获取PDF文档属性并将其附加到StringBuilder中
            content.Append("标题: " + pdf.DocumentInformation.Title + "\r\n");
            content.Append("作者: " + pdf.DocumentInformation.Author + "\r\n");
            content.Append("主题: " + pdf.DocumentInformation.Subject + "\r\n");
            content.Append("关键字: " + pdf.DocumentInformation.Keywords + "\r\n");
            content.Append("PDF生成器: " + pdf.DocumentInformation.Producer + "\r\n");

            //将StringBuilder写入TXT文件
            File.WriteAllText("获取PDF属性.txt", content.ToString());
        }
    }
}
Imports Spire.Pdf
Imports System.IO
Imports System.Text

Namespace GetPdfProperties
    Friend Class Program
        Private Shared Sub Main(ByVal args As String())
            '创建一个PdfDocument实例
            Dim pdf As PdfDocument = New PdfDocument()

            '加载PDF文件
            pdf.LoadFromFile("Pdf属性.pdf")

            '创建StringBuilder实例
            Dim content As StringBuilder = New StringBuilder()

            '获取PDF文档属性并将其附加到StringBuilder中
            content.Append("标题: " & pdf.DocumentInformation.Title.ToString().ToString() & vbCrLf)
            content.Append("作者: " & pdf.DocumentInformation.Author.ToString().ToString() & vbCrLf)
            content.Append("主题: " & pdf.DocumentInformation.Subject.ToString().ToString() & vbCrLf)
            content.Append("关键字: " & pdf.DocumentInformation.Keywords.ToString().ToString() & vbCrLf)
            content.Append("PDF生成器: " & pdf.DocumentInformation.Producer.ToString().ToString() & vbCrLf)

            '将StringBuilder写入TXT文件
            Call File.WriteAllText("获取PDF属性.txt", content.ToString())
        End Sub
    End Class
End Namespace

C#/VB.NET 设置或获取 PDF 属性

申请临时 License

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

在PDF文档中,自定义文档属性可以用来存储特定的元数据类型,例如版本号或公司名称等。我们可以给一个PDF文档添加自定义文档属性,同时也可以查看和删除PDF文档中已有的自定义属性。

本文将介绍如何使用Spire.PDF组件在PDF文档中添加、获取和删除自定义文档属性。

添加自定义文档属性

C#
//实例化一个PdfDocument对象
            PdfDocument doc = new PdfDocument();
            //载入PDF文档
            doc.LoadFromFile("Input.pdf");

            //添加自定义文档属性
            doc.DocumentInformation.SetCustomProperty("版本号", "6.0.5");
            doc.DocumentInformation.SetCustomProperty("公司名称", "E-iceblue");
            doc.DocumentInformation.SetCustomProperty("产品", "Spire.Doc for .NET");

            //保存文档
            doc.SaveToFile("添加自定义属性.pdf");
VB.NET
'实例化一个PdfDocument对象
   Dim doc As New PdfDocument()
   '载入PDF文档
   doc.LoadFromFile("Input.pdf")

   '添加自定义文档属性
   doc.DocumentInformation.SetCustomProperty("版本号", "6.0.5");
   doc.DocumentInformation.SetCustomProperty("公司名称", "E-iceblue");
   doc.DocumentInformation.SetCustomProperty("产品", "Spire.Doc for .NET");

   '保存文档
   doc.SaveToFile("添加自定义属性.pdf")

C# 添加、获取和删除 PDF 自定义文档属性

获取自定义文档属性

C#
//实例化一个PdfDocument对象
PdfDocument doc = new PdfDocument();
//载入PDF文档
doc.LoadFromFile("添加自定义属性.pdf");

//获取指定自定义属性
string version = doc.DocumentInformation.GetCustomProperty("版本号");
string company = doc.DocumentInformation.GetCustomProperty("公司名称");
string product = doc.DocumentInformation.GetCustomProperty("产品");

//获取所有自定义文档属性
//Dictionary<string, string> allCustomProperties = doc.DocumentInformation.GetAllCustomerDefined();            

Console.WriteLine("{0}\n{1}\n{2}\n", "版本号:" + version, "公司名称:" + company, "产品:" + product);
VB.NET
'实例化一个PdfDocument对象
 Dim doc As New PdfDocument()
 '载入PDF文档
 doc.LoadFromFile("添加自定义属性.pdf")

 '获取指定自定义属性
 Dim version As String = doc.DocumentInformation.GetCustomProperty("版本号")
 Dim company As String = doc.DocumentInformation.GetCustomProperty("公司名称")
 Dim product As String = doc.DocumentInformation.GetCustomProperty("产品")

 '获取所有自定义文档属性
 'Dictionary allCustomProperties = doc.DocumentInformation.GetAllCustomerDefined();            

 Console.WriteLine("{0}" & vbLf & "{1}" & vbLf & "{2}" & vbLf, Convert.ToString("版本号:") & version, Convert.ToString("公司名称:") & company, Convert.ToString("产品:") & product)

C# 添加、获取和删除 PDF 自定义文档属性

删除自定义文档属性

C#
//实例化一个PdfDocument对象
     PdfDocument doc = new PdfDocument();
     //载入PDF文档
     doc.LoadFromFile("添加自定义属性.pdf");

     //删除指定自定义属性
     doc.DocumentInformation.RemoveCustomProperty("版本号");

     //保存文档            
     doc.SaveToFile("删除自定义属性.pdf");
VB.NET
'实例化一个PdfDocument对象
     Dim doc As New PdfDocument()
     '载入PDF文档
     doc.LoadFromFile("添加自定义属性.pdf")

     '删除指定自定义属性
     doc.DocumentInformation.RemoveCustomProperty("版本号")

     '保存文档            
     doc.SaveToFile("删除自定义属性.pdf")

C# 添加、获取和删除 PDF 自定义文档属性

如何使用 C# .NET 编辑 PDF

PDF(可移植文档格式)因其在跨平台环境下保持一致的布局和格式而被广泛用于文档共享、分发和存档。在PDF 文档开发过程中,开发者常常需要通过程序对 PDF 文件进行编辑操作,例如替换文本、插入图片、添加水印或提取页面等。

在本教程中,你将学习如何使用 Spire.PDF for .NET 库通过编程方式在 C# 中编辑 PDF 文件。

目录

为什么要使用 C# 编辑 PDF

尽管 Adobe Acrobat 等工具提供手动编辑 PDF 的功能,但通过 C# 编程方式编辑 PDF 有显著优势:

  • 自动化:可批量处理数百个文档,无需人工干预。
  • 集成性:可作为工作流的一部分自动生成报表、发票或证书等。
  • 一致性:在多个 PDF 上统一应用样式、水印或标记。
  • 灵活性:可从数据库或外部数据源提取或替换内容,实现高度定制。

C# PDF 编辑库

Spire.PDF for .NET 是一个功能强大的 .NET PDF 库,可让开发者在 .NET 应用中生成、读取、编辑和转换 PDF 文件,支持 .NET Framework 和 .NET Core。

Spire.PDF - C# PDF 编辑库

该库为开发者提供了丰富的PDF操作功能:

  • PDF 创建:从零生成 PDF,或基于现有文档创建。
  • 文本编辑:在任意页面添加、替换或删除文本。
  • 图片编辑:插入、调整大小或删除图片。
  • 页面操作:添加、删除、提取或重新排序页面。
  • 注释:添加印章、批注或标记内容。
  • 水印:添加文本或图片水印以实现版权保护。
  • 表单处理:创建和填写 PDF 表单。
  • 数字签名:添加并验证签名确保文件真实性。
  • 加密:应用密码保护和用户权限控制。

C# 编辑 PDF 分步详解

在 C# 中修改 PDF 文件通常涉及以下步骤:创建项目、安装库、加载 PDF、进行必要修改、保存文档。以下是每一步的详细说明。

步骤 1:创建 C# 项目

在开始编辑 PDF 之前,需要创建一个新的 C# 项目:

  • 打开 Visual Studio。
  • 创建一个新项目,可选择控制台应用或 Windows 窗体应用,视实际需求而定。
  • 命名项目(例如 PdfEditorDemo),然后点击"创建"。

步骤 2:安装 Spire.PDF

接下来,需要安装 Spire.PDF 库,它提供读取、编辑和保存 PDF 所需的全部功能。

可以通过 NuGet 包管理器控制台安装:

Install-Package Spire.PDF

或者通过 NuGet 包管理器 GUI 搜索 Spire.PDF 并点击安装。

步骤 3:加载已有 PDF

在对已有 PDF 文件进行修改之前,需要先将其加载到 PdfDocument 对象中,以便访问文档的页面、文本和图片等内容。

using Spire.Pdf;

PdfDocument pdf = new PdfDocument();
pdf.LoadFromFile("示例.pdf");

步骤 4:修改 PDF 文档内容

编辑文本、插入图片、管理页面和添加水印是 PDF 开发中的常见操作。下面将逐一介绍这些操作,并附上示例代码说明。

4.1 编辑文本

文本编辑是 PDF 中最常见的操作。你可以选择替换已有文本或在特定页面添加新文本。

替换已有文本:

在 PDF 中替换文本可以针对单页或整个文档更新内容,同时保持原有格式不变。使用 PdfTextReplacer 类,可快速实现文本的查找与替换操作:

// 获取第一页
PdfPageBase page = pdf.Pages[0];
// 创建 PdfTextReplacer 对象
PdfTextReplacer textReplacer = new PdfTextReplacer(page);

// 将所有目标文本替换为新文本
textReplacer.ReplaceAllText("旧文本", "新文本");

添加新文本:

除了替换已有文本,还可以在 PDF 页面任意位置添加新文本,只需一行代码:

page.Canvas.DrawString(
    "你好,世界!",
    new PdfTrueTypeFont(new Font("宋体", 15f, FontStyle.Bold), true),
    new PdfSolidBrush(Color.Black),
    90, 30
);

4.2 插入与更新图片

PDF 文档中通常包含视觉元素,如徽标、图表或插图。开发者可以在PDF中插入新图片,或者更新旧图片以增强文档的视觉效果。

插入图片:

// 加载图片
PdfImage image = PdfImage.FromFile("logo.png");
// 在指定位置绘制图片,并设置大小
page.Canvas.DrawImage(image, 100, 150, 200, 100);

更新图片:

// 加载新图片
PdfImage newImage = PdfImage.FromFile("image1.jpg");
// 创建 PdfImageHelper 实例
PdfImageHelper imageHelper = new PdfImageHelper();
// 获取页面上的图片信息
PdfImageInfo[] imageInfo = imageHelper.GetImagesInfo(page);
// 用新图片替换页面上的第一张图片
imageHelper.ReplaceImage(imageInfo[0], newImage);

4.3 添加、删除或提取页面

页面管理是 PDF 编辑的另一个重要方面,包括添加新页面、删除不需要的页面,以及将特定页面提取到新文档。

添加新页面:

// 添加新页面
PdfPageBase newPage = pdf.Pages.Add();

删除页面:

// 删除最后一页
pdf.Pages.RemoveAt(pdf.Pages.Count - 1);

提取页面到新文档:

// 创建新 PDF 文档
PdfDocument newPdf = new PdfDocument();
// 将原文档的第三页提取到新 PDF
newPdf.InsertPage(pdf, pdf.Pages[2]);
// 保存新 PDF
newPdf.SaveToFile("提取页面.pdf");

4.4 添加水印

在 PDF 中添加水印可帮助标识机密信息、添加品牌或保护知识产权。开发者可以通过代码在任意页面上轻松添加水印:

// 遍历 PDF 文档的每一页
foreach (PdfPageBase page in pdf.Pages)
{
    // 创建一个平铺画刷(Tiling Brush),尺寸为页面宽度的一半,高度为页面高度的三分之一
    PdfTilingBrush brush = new PdfTilingBrush(
        new SizeF(page.Canvas.ClientSize.Width / 2, page.Canvas.ClientSize.Height / 3));

    // 设置透明度为 0.3,使水印半透明
    brush.Graphics.SetTransparency(0.3f);

    // 保存当前图形状态,方便后续恢复
    brush.Graphics.Save();

    // 将坐标原点移动到画刷中心
    brush.Graphics.TranslateTransform(brush.Size.Width / 2, brush.Size.Height / 2);

    // 将坐标系旋转 -45 度,使水印呈斜角
    brush.Graphics.RotateTransform(-45);

    // 在画刷上绘制文字“DO NOT COPY”,如需绘制中文,需使用PdfTrueTypeFont并改为中文字体
    // 使用 Helvetica 字体,字号 24,颜色为紫罗兰色,文字居中
    brush.Graphics.DrawString(
        "DO NOT COPY",
        new PdfFont(PdfFontFamily.Helvetica, 24),
        PdfBrushes.Violet,
        0, 0,
        new PdfStringFormat(PdfTextAlignment.Center));

    // 恢复之前保存的图形状态
    brush.Graphics.Restore();

    // 重置透明度为 1(不透明)
    brush.Graphics.SetTransparency(1);

    // 将画刷绘制到页面整个区域,实现水印效果
    page.Canvas.DrawRectangle(brush, new RectangleF(new PointF(0, 0), page.Canvas.ClientSize));
}

步骤 5:保存修改后的 PDF

完成所有编辑后,最后一步是保存修改并释放资源:

// 保存修改后的 PDF 并释放资源
pdf.SaveToFile("修改.pdf");
pdf.Close();

输出PDF文档:

C# 编辑 PDF 输出效果

提高 C# PDF 编辑效率的技巧

在程序化编辑 PDF 时,遵循以下实用技巧,可以确保输出准确、可读且高效:

  • 批量处理:对于重复任务,通过循环处理多个 PDF 文件,而非单独处理,提高效率并减少人工操作。
  • 文本位置:插入新文本时,注意坐标,防止与现有内容重叠,保持版面整洁。
  • 字体与编码:选择支持所需字符的字体,尤其是中文、阿拉伯文或其他扩展字符。
  • 内存管理:使用完 PdfDocument 对象后及时释放资源,以避免大文件处理时性能问题。

总结

本教程介绍了如何使用 Spire.PDF 在 C# 中编辑 PDF 文件,涵盖文本替换、图片插入、页面管理及水印添加等操作。每个步骤均提供实用代码示例,帮助开发者通过程序化方式高效处理 PDF,提高文档操作效率与专业性。

常见问题解答

Q1:如何在 C# 中使用 Spire.PDF 编辑 PDF 文本?

A1: 使用 Spire.PDF,可以替换已有文本或添加新文本。PdfTextReplacer 和 page.Canvas.DrawString() 提供精确控制,同时保持 PDF 格式一致。

Q2:在 C# 中如何替换或添加 PDF 文本?

A2: 通过 PdfTextReplacer 查找并替换文本,或使用 page.Canvas.DrawString() 在任意位置添加新文本,实现程序化 PDF 编辑。

Q3:可以在 C# 中插入或更新 PDF 图片吗?

A3: 可以,使用 PdfImage 和 PdfImageHelper 将图片绘制或替换到 PDF 页面上,支持图像更新和插入操作。

Q4:如何用代码为 PDF 添加水印?

A4: 可使用 C# 和 Spire.PDF 程序化添加文本或图片水印,并控制透明度、旋转和位置,可应用于单页或所有页面。

Q5:如何在 C# 中提取 PDF 的特定页面?

A5: 创建新的 PDF 文档,将原文档的指定页面插入新文档,实现单页或页范围提取,便于程序化处理 PDF 文件。

C++ 图像转 OFD 教程

在 C++ 中将图像转换为 OFD(Open Fixed-layout Document)格式,是文档处理系统中的常见需求。尤其在中国,OFD 已成为官方文档归档、交换和分发的重要标准格式。在实际开发过程中,开发人员往往需要将扫描文档或图片文件转换为 OFD 文档,以便统一存储、归档,或集成到电子文档管理系统和自动化工作流程中。

如果从底层自行实现图像到 OFD 的转换,通常需要处理图像格式解析、页面尺寸设置以及文档结构构建等复杂细节,同时还要确保生成的文件符合 OFD 规范。借助 Spire.PDF for C++,开发人员可以通过简洁的 API 快速实现图像到 OFD 的转换。该库支持 PNG、JPG、BMP、TIFF 和 EMF 等常见图像格式,并自动处理文档结构和渲染过程。

本文将介绍如何在 C++ 中实现图像转换为 OFD 文档,并提供单图像转换、多图像生成多页 OFD 以及批量转换等实用示例。

快速导航

  1. 了解图像到 OFD 转换
  2. 准备工作
  3. 在 C++ 中将单个图像转换为 OFD
  4. 在 C++ 中将多个图像转换为多页 OFD
  5. 将图像适配到固定页面大小
  6. 批量将单个图像转换为单个 OFD
  7. 常见问题与注意事项
  8. 常见问题解答

1. 了解图像到 OFD 转换

OFD 是一种基于 XML 的固定版式文档格式,其功能与 PDF 类似,但在字符集支持和政府文档标准方面针对中文环境进行了优化。

将图像转换为 OFD,本质上是创建一个符合 OFD 规范的文档结构,并将图像内容嵌入到文档页面中。

图像转 OFD 的常见应用场景包括:

  • 将扫描发票或收据进行数字化归档
  • 构建统一的电子文档存储系统
  • 搭建自动化文档处理流程
  • 将传统图像文档转换为标准化电子文档

在实际实现中,通常的处理流程是:创建文档对象,将图像绘制到页面上,然后按照 OFD 规范导出为 OFD 文件。

2. 准备工作

在 C++ 中实现图像到 OFD 的转换之前,需要先安装并配置 Spire.PDF for C++。

通过 NuGet 安装(推荐)

将 Spire.PDF 添加到 C++ 项目的最简单方式是使用 NuGet,它会自动下载库文件并配置相关依赖。

安装步骤如下:

  1. 在 Visual Studio 中打开项目
  2. 在 解决方案资源管理器 中右键单击 引用
  3. 选择 管理 NuGet 程序包
  4. 搜索 Spire.PDF.Cpp
  5. 点击 安装

安装完成后,可以在代码中引入该库:

#include "Spire.Pdf.o.h"

手动安装

您也可以 下载 Spire.PDF for C++,然后通过配置 include 和 lib 目录手动将其集成到项目中。

详细说明请参考:

如何在 C++ 应用程序中集成 Spire.PDF for C++

3. 在 C++ 中将单个图像转换为 OFD

下面的示例演示如何将单个图像文件转换为 OFD 文档。代码首先创建一个 PDF 文档对象,然后加载图像并将其绘制到页面上,最后将文档保存为 OFD 格式。

#include "Spire.Pdf.o.h"

using namespace Spire::Pdf;

int main()
{
    // 创建新的 PDF 文档
    PdfDocument* ofd = new PdfDocument();

    // 加载图像文件
    auto image = PdfImage::FromFile(L"Sample.jpg");

    // 根据图像尺寸计算页面大小
    float pageWidth = image->GetWidth();
    float pageHeight = image->GetHeight();

    // 添加与图像尺寸匹配的页面
    auto page = ofd->GetPages()->Add(new SizeF(pageWidth, pageHeight));

    // 在页面上绘制图像
    page->GetCanvas()->DrawImage(image, 0, 0, pageWidth, pageHeight);

    // 保存为 OFD 文件
    ofd->SaveToFile(L"ImageToOfd.ofd", FileFormat::OFD);

    // 释放资源
    delete ofd;

    return 0;
}

以下截图展示了由源图像生成的 OFD 文档效果。

C++ 图像转 OFD 效果

核心类与方法

  • PdfDocument 表示文档对象,用于创建页面并导出最终的 OFD 文件。

  • PdfImage::FromFile() 从指定路径加载图像文件,并创建可绘制到页面上的图像对象。

  • PdfDocument::GetPages()->Add() 向文档中添加新页面。本示例根据图像尺寸动态设置页面大小。

  • PdfCanvas::DrawImage() 将图像绘制到页面画布的指定位置和尺寸。

  • SaveToFile() 将文档保存到磁盘,并使用 FileFormat::OFD 指定输出格式为 OFD。

这种方式可以确保图像在 OFD 页面中以正确比例显示,从而保持原始图像质量。

移除页面边距(可选)

默认情况下,文档页面可能包含边距,这会导致图像周围出现空白区域。如果希望图像完全填充页面,可以将页面边距设置为 0:

ofd->GetPageSettings()->SetMargins(0.0);

如果需要保留一定留白,也可以自定义边距:

ofd->GetPageSettings()->SetMargins(10.0);

合理设置边距有助于控制页面布局效果。

注意:如果代码运行时出现 C++ 版本兼容性问题,可通过如下方式解决:

  • 方法一:在 项目属性 → C/C++ → 预处理器 → 预处理器定义 中添加 _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING
  • 方法二:在 项目属性 → 配置属性 → 常规 中,将 C++ 语言标准 设置为 ISO C++14 标准 (/std:c++14)

4. 在 C++ 中将多个图像转换为多页 OFD

在文档归档或批量处理场景中,通常需要将多张图像合并到同一个 OFD 文件中。下面的示例展示了如何创建一个多页 OFD 文档,并在每个页面中放置一张不同的图像。

代码会遍历图像文件列表,为每张图像创建独立页面,并根据图像尺寸设置页面大小,然后将图像绘制到对应页面中。

#include "Spire.Pdf.o.h"
#include <vector>
#include <filesystem>
#include <algorithm>

using namespace Spire::Pdf;
namespace fs = std::filesystem;

int main()
{
    // 创建新的 PDF 文档(用于保存为 OFD)
    PdfDocument* ofd = new PdfDocument();

    // 指定图片文件夹
    std::wstring folderPath = L"./images";

    // 遍历文件夹
    for (const auto& entry : fs::directory_iterator(folderPath))
    {
        if (!entry.is_regular_file())
            continue;

        std::wstring path = entry.path().wstring();
        std::wstring ext = entry.path().extension().wstring();

        // 转为小写方便比较
        std::transform(ext.begin(), ext.end(), ext.begin(), ::towlower);

        // 判断是否为支持的图片格式
        if (ext == L".png" || ext == L".jpg" || ext == L".jpeg" || ext == L".bmp")
        {
            // 加载图片
            auto image = PdfImage::FromFile(path.c_str());

            // 获取图片尺寸
            float pageWidth = image->GetWidth();
            float pageHeight = image->GetHeight();

            // 创建页面
            auto page = ofd->GetPages()->Add(new SizeF(pageWidth, pageHeight));

            // 绘制图片
            page->GetCanvas()->DrawImage(image, 0, 0, pageWidth, pageHeight);
        }
    }

    // 保存为 OFD
    ofd->SaveToFile(L"multi_page_document.ofd", FileFormat::OFD);

    delete ofd;

    return 0;
}

以下截图展示了生成的多页 OFD 文档,每张图像分别置于独立页面。

C++ 多图转多页 OFD

此实现遍历图像文件集合,为每张图像创建独立页面,并以恰当的尺寸绘制内容。生成的 OFD 文档在单一文件中保留所有源图像的顺序和版式。

注意: #include <filesystem> 仅在 C++ 17 及以上的 C++ 标准下可用。

如果需要对已经转换出的 OFD 文档进行合并操作,请参考 如何使用 C++ 合并 OFD/PDF 文档。

5. 将图像适配到固定页面大小

在许多实际文档工作流中,页面通常需要遵循 标准页面尺寸,而不是直接使用图像原始尺寸。例如,扫描的合同、表格或报告往往需要统一为 A4 或 Letter 等标准页面格式。

要实现这一点,可以先创建具有固定尺寸的页面,然后按照比例缩放图像,使其在不变形的情况下适应页面范围。

下面的示例演示了如何在保持纵横比的前提下,将图像缩放并适配到固定页面大小。

#define NOMINMAX
#include "Spire.Pdf.o.h"
#include <algorithm>

using namespace Spire::Pdf;

int main()
{
    // 创建新的 PDF 文档
    PdfDocument* ofd = new PdfDocument();

    // 添加固定尺寸的页面(如 A4)
    PdfPageBase* page = ofd->GetPages()->Add(PdfPageSize::A4);

    // 加载图像
    auto image = PdfImage::FromFile(L"Sample.jpg");

    // 获取页面尺寸
    float pageWidth = page->GetCanvas()->GetClientSize().GetWidth();
    float pageHeight = page->GetCanvas()->GetClientSize().GetHeight();

    // 获取图像尺寸
    float imgWidth = image->GetWidth();
    float imgHeight = image->GetHeight();

    // 计算等比缩放比例
    float scale = std::min(pageWidth / imgWidth, pageHeight / imgHeight);

    float scaledWidth = imgWidth * scale;
    float scaledHeight = imgHeight * scale;

    // 在页面上绘制缩放后的图像
    page->GetCanvas()->DrawImage(image, 0, 0, scaledWidth, scaledHeight);

    // 保存为 OFD
    ofd->SaveToFile(L"FixedPageSize.ofd", FileFormat::OFD);

    delete ofd;

    return 0;
}

以下截图展示了图像如何缩放以适应固定页面尺寸(A4),同时保持其纵横比。

C++ OFD 中图像缩放适配 A4 页面

这种方法确保不同尺寸的图像可以统一放置在标准化文档版式中,同时保持原始比例,避免图像变形。相同技术也可应用于从多张图像生成多页 OFD 文档的场景。

6. 批量将单个图像转换为单个 OFD

在自动化文档处理系统中,往往需要将大量图像文件批量转换为 OFD 文档。为了提高代码复用性,可以将转换逻辑封装为独立函数,并通过循环处理多个文件。

下面的示例演示了一种简单的批量处理实现方式,同时包含基本的错误处理和进度输出。

#include "Spire.Pdf.o.h"
#include <vector>
#include <iostream>
#include <filesystem>
#include <algorithm>

using namespace Spire::Pdf;
namespace fs = std::filesystem;

void ConvertImageToOFD(const std::wstring& inputPath, const std::wstring& outputPath)
{
    // 创建新的 PDF 文档(用于生成 OFD)
    PdfDocument* ofd = new PdfDocument();

    try
    {
        // 加载图像文件
        auto image = PdfImage::FromFile(inputPath.c_str());

        // 计算页面尺寸(与图像尺寸保持一致)
        float pageWidth = image->GetWidth();
        float pageHeight = image->GetHeight();

        // 添加与图像尺寸匹配的页面
        auto page = ofd->GetPages()->Add(new SizeF(pageWidth, pageHeight));

        // 在页面上绘制图像
        page->GetCanvas()->DrawImage(image, 0, 0, pageWidth, pageHeight);

        // 保存为 OFD
        ofd->SaveToFile(outputPath.c_str(), FileFormat::OFD);

        std::wcout << L"已转换:" << inputPath << L" -> " << outputPath << std::endl;

    }
    catch (const std::exception& ex)
    {
        std::wcout << L"转换 " << inputPath << L" 时出错:" << ex.what() << std::endl;
    }

    // 清理文档
    delete ofd;
}

int main()
{
    // 定义要遍历的图片文件夹
    std::wstring folderPath = L"./images";

    // 遍历文件夹中的所有文件,并自动执行转换
    for (const auto& entry : fs::directory_iterator(folderPath))
    {
        // 仅处理普通文件
        if (!entry.is_regular_file())
            continue;

        fs::path filePath = entry.path();
        std::wstring ext = filePath.extension().wstring();

        // 将扩展名转换为小写以便统一比较
        std::transform(ext.begin(), ext.end(), ext.begin(), ::towlower);

        // 判断是否为支持的图像格式
        if (ext == L".png" || ext == L".jpg" || ext == L".jpeg" || ext == L".bmp")
        {
            // 获取输入图像路径
            std::wstring inputPath = filePath.wstring();

            // 生成对应的 OFD 输出路径(与图像同名)
            fs::path outputPath = filePath.parent_path() / (filePath.stem().wstring() + L".ofd");

            // 执行转换
            ConvertImageToOFD(inputPath, outputPath.wstring());
        }
    }

    std::wcout << L"批量转换完成。" << std::endl;

    return 0;
}

这种批处理方式提供:

  • 可复用的模块化转换函数
  • 针对单个文件失败的错误处理机制
  • 便于监控的进度输出
  • 清晰的资源管理

该实现独立处理每张图像,确保单个失败不会中断整个批量操作。

7. 注意事项

图像文件路径问题

确保图像文件路径正确且可访问。加载图像时建议使用绝对路径或验证工作目录:

// 为提高可靠性,使用绝对路径
auto image = PdfImage::FromFile(L"C:\\Documents\\scanned_invoice.png");

内存管理

妥善清理 PdfDocument 和 PdfImage 对象以防止内存泄漏。使用后务必删除动态分配的对象:

delete ofd;

不支持的图像格式

Spire.PDF 支持常见图像格式,包括 PNG、JPEG、BMP、EMF 和 TIFF。请确保输入文件采用受支持的格式。对于不受支持的格式,需先使用图像处理库将其转换为受支持格式。

页面尺寸注意事项

当基于图像尺寸创建页面时,请注意过大的图像可能导致生成的 OFD 文档难以查看或打印。建议对大图像实施尺寸限制或缩放处理:

#define NOMINMAX
#include <algorithm>

// 应用最大页面尺寸限制
const float MAX_WIDTH = 1000.0f;
const float MAX_HEIGHT = 1400.0f;

float pageWidth  = std::min(static_cast<float>(image->GetWidth()),  MAX_WIDTH);
float pageHeight = std::min(static_cast<float>(image->GetHeight()), MAX_HEIGHT);

文件编码

处理包含中文字符或特殊符号的文件路径时,应使用宽字符串(std::wstring)以确保正确的编码处理,避免文件操作中出现编码问题。

C++ 语言标准

如果在某些环境中遇到编译问题,可尝试在 项目属性 → C/C++ → 预处理器 → 预处理器定义 中添加 _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;也可在 项目属性 → 配置属性 → 常规 中,将 C++ 语言标准 设置为 ISO C++14 标准 (/std:c++14)。

总结

本文介绍了如何使用 Spire.PDF for C++ 将图像转换为 OFD 文档。通过简单的 API 调用,开发人员即可实现单图像转换、多图像生成多页文档以及批量转换等功能。

该技术在扫描文档数字化、电子档案管理以及自动化文档处理流程中具有广泛应用。

除了 OFD 转换外,Spire.PDF for C++ 还提供丰富的 PDF 文档处理能力,包括 PDF 创建、编辑、转换以及多种格式导出等功能。借助该库,开发人员可以高效完成复杂的文档处理任务,同时确保生成文档符合相关行业标准。

如需体验完整功能,可 申请 30 天免费许可证。

8. 常见问题解答

将图像转换为 OFD 是否需要第三方软件?

不需要。Spire.PDF 可以独立完成图像到 OFD 的转换,无需依赖 Adobe Acrobat 或其他外部 PDF 软件。

OFD 转换支持哪些图像格式?

Spire.PDF 支持常见图像格式,包括 PNG、JPEG、BMP、EMF 和 TIFF。

Spire.PDF 是否适用于批量处理?

是的。Spire.PDF 针对服务器环境进行了优化,可以高效处理大量图像转换任务。

转换前可以添加水印或文本吗?

可以。Spire.PDF 允许在页面画布上绘制文本或图片,因此可以在导出为 OFD 前添加水印。

相关教程:

OFD 输出会影响图像质量吗?

不会。转换过程中会保留原始图像的分辨率和质量,页面尺寸也会根据图像大小进行适配。

Spire.Doc 14.3 现已发布。本次更新新增支持“定义网格时自动调整为右缩进”与“为字体调整字间距”功能,同时提供多个新接口用于添加与操作 SmartArt 图形。此外,三个在操作 Word 文档时出现问题也已成功被修复。详情如下。

新功能:

问题修复:


获取Spire.Doc 14.3,请点击:

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

Spire.PDF for Java 12.3.2 现已正式发布。该版本支持设置 PDF 2.0 版本,同时修复了一些问题,例如中文文本绘制时标点符号位于行首的问题。更多详情如下。

新功能:

问题修复:


获取 Spire.PDF for Java 12.3.2 请点击:

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