跳到主要内容

PDF4me .NET SDK: C# PDF 图书馆和 API 客户

Pdf4me.Client 是一个 .NET 客户端库 PDF4me API 它公开了 106 个文档操作,作为类型化的异步方法。从以下位置安装: NuGet创建一个 Pdf4meClient 你的 API 关键,以及转换、优化、合并、拆分 OCR 或从文档中提取 C# 无需自带渲染引擎。

包装信息​

场地价值
软件包名称Pdf4me.Client
当前版本2.0.0 (最后更新日期:2026年10月13日)
执照MIT
.NET 支持.NET 8、9 和 10,加上 .NET 标准 2.0 .NET Framework 4.6.2 及更高版本
总下载量所有版本共计 246.4K
包装尺寸1.34 MB
行动106,共18个部分
运行时依赖项Microsoft.Kiota.Bundle (>= 2.1.2)和 Microsoft.Extensions.Logging.Abstractions (>= 8.0.3)
根据 URLhttps://api.pdf4me.com
来源github.com/pdf4me/pdf4me-clientapi-dotnet
NuGetnuget.org/packages/Pdf4me.Client

先决条件​

  • .NET 8 或更新版本,或 .NET 框架 4.6.2 或更高版本 .NET 标准 2.0。
  • A PDF4me 账户和 API 钥匙。

安装​

dotnet add package Pdf4me.Client

认证​

设置你的 API 环境中的关键因素:

export PDF4ME_API_KEY="your-api-key"

在Windows系统上, set 仅持续到当前 CMD 会话。使用 setx PDF4ME_API_KEY "your-api-key" 如果某个值在重启后仍然存在,则打开一个新的终端,以便进程可以获取该值。

客户端在其构造函数中接受该键。它记录的任何内容都不包含该键。 API 键或文档内容,以及空键或仅包含空白字符的键都会抛出异常。 ArgumentException 在任何请求发出之前。

快速入门​

该程序上传 input.pdf 为了进行优化并将结果保存为 optimized.pdf:

using Pdf4me.Client;

var apiKey = Environment.GetEnvironmentVariable("PDF4ME_API_KEY")
?? throw new InvalidOperationException("Set PDF4ME_API_KEY first.");

using var client = new Pdf4meClient(apiKey);
var result = await client.OptimizeAsync(
File.ReadAllBytes("input.pdf"), docName: "input.pdf", profile: OptimizeProfile.Max);
File.WriteAllBytes("optimized.pdf", result);

创建一个客户端,并将其用于每次调用。它维护一个连接池,因此每次调用都会使用一个客户端进行协商。 TLS 每次都用完。用完后请丢弃。

什么是 PDF4me .NET SDK?​

这是一个单独的 NuGet 包裹, Pdf4me.Client包裹着 PDF4me API v2 版本由一个类控制。每个操作都是一个异步方法。 Pdf4meClient 以其终点命名,所以 /api/v2/ConvertOcrPdf 是 ConvertOcrPdfAsync第一个参数决定了操作所针对的对象,其他参数都是可选的,所以可以通过名称传递:

var searchable = await client.ConvertOcrPdfAsync(
scan, language: "English", qualityType: QualityType.Draft);

var numbered = await client.AddPageNumberAsync(
pdf, pageNumberFormat: "Page # of {1}", alignX: AddPageNumberAlignX.Center);

这 Generated 包内的树是由……生成的 Microsoft Kiota 从 PDF4me OpenAPI 描述,这就是为什么选项和结果模型与……一致的原因 REST API 并且与 Python 和 JavaScript 客户端:相同的操作,相同的名称和默认值。

C# PDF 库与 API 客户端有何不同?​

“搜索结果最多”c# pdf “库”是自托管渲染库:您添加该包,它会在您的进程中完成工作,并且您拥有渲染引擎。 Pdf4me.Client 是另一种形状。它将文档发送到 PDF4me 并返回最终的字节。这种交易是双向的,所以有必要坦诚相告:

本地图书馆与托管图书馆 API自托管库Pdf4me.Client
工作发生的地方在你的过程中在 PDF4me 服务
需要网络不是的,每次通话
成本形状软件包许可,有时按开发者或按部署次数计费。MIT 客户, API 免费或付费计划中的积分
可离线或物理隔离环境下工作是的不
文档离开您的基础设施不是的
OCR, AI 提取, ZUGFeRD通常情况下,如果有的话,会单独出售。包含在这 106 项行动中
你保持引擎、它的字体和它的 CVEs一个 API 钥匙

如果文档不能离开您的网络、需要离线工作,或者按文档数量计费比订阅更划算,请选择本地库。如果您需要集成多个产品才能完成转换,请选择此客户端。 OCR条形码、电子发票和 AI 提取,而且你宁愿根本不发布或修补渲染引擎。

请注意,自动完成功能询问的关于此类别的两个问题,在此处的答案有所不同。客户本身是 MIT 许可和开源因此,您链接的代码符合“免费”和“开源”的条件。但其背后的处理过程是由托管服务提供的,超出免费套餐后则需要付费。

传递文件并阅读结果​

文件 区域 DocumentSource:可以是文件的字节,也可以是字符串 API 它获取自身,这可能是一个 pdf4meblobid://<id> blob 引用或 https URL两者都会隐式转换,因此可以直接传入。字符串永远不会被读取为本地文件路径,所以需要读取文件并传入其字节。

byte[] fromBytes = await client.OptimizeAsync(File.ReadAllBytes("report.pdf"));
byte[] fromUrl = await client.OptimizeAsync("https://example.com/report.pdf");
byte[] fromBlob = await client.OptimizeAsync("pdf4meblobid://<id>");

结果 返回结果有两种方式。生成文档的操作会返回其结果。 byte[], 所以 File.WriteAllBytes 直接接收数据。而返回数据响应的操作则会返回一个类型化的模型:

DocMetadata metadata = await client.GetPdfMetadataAsync(pdf);
Console.WriteLine($"{metadata.PageCount} pages, PDF {metadata.PdfVersion}");

ReadBarcodesRes scan = await client.ReadBarcodesAsync(pdf);
foreach (var barcode in scan.Barcodes ?? [])
Console.WriteLine($"page {barcode.Page}: {barcode.Value}");

这 AI 文档解析器自行决定响应格式,因此它返回的所有内容都会到达模型。 AdditionalData:

var parsed = await client.AiDocumentParserAsync(File.ReadAllBytes("invoice.pdf"), "invoice parser");
foreach (var (field, value) in parsed.AdditionalData)
Console.WriteLine($"{field}: {value}");

多份文件 按给定顺序合并,某些操作根本不需要文档,因为输入是文本或 URL:

byte[] merged = await client.MergeAsync([File.ReadAllBytes("a.pdf"), File.ReadAllBytes("b.pdf")]);
byte[] qrCode = await client.CreateBarcodeAsync("https://pdf4me.com", barcodeType: CreateBarcodeBarcodeType.QRCode);
byte[] webPage = await client.ConvertUrlToPdfAsync("https://example.com");

选项是对象, 例如 ConvertToPdfAction 和 ImageAction以及所有结果模型,都存在于 Pdf4me.Client.Generated.Models枚举中,操作所采取的行动都有简短的名称。 Pdf4me.Client (QualityType, AlignX, SplitAction),而少数生成的名称已经很短(DocType, ImageTypeExtract) 直接从生成的命名空间中使用:

using Pdf4me.Client;
using Pdf4me.Client.Generated.Models;

var pages = await client.CreateImagesAsync(
pdf, new ImageAction { ImageExtension = ImageExtension.Png }, pageNrs: "1");

每个行动也都会产生影响 三个可选参数: extra一个包含选项附加请求字段的字典 API 描述尚未列出,与操作本身一起发送; maxWait这会限制该调用队列中任务的等待时间; cancellationToken这会取消请求和任何轮询。

客户端配置​

using var client = new Pdf4meClient(apiKey, new Pdf4meClientOptions
{
BaseUrl = Pdf4meClient.DefaultBaseUrl, // https://api.pdf4me.com
Timeout = TimeSpan.FromSeconds(100), // each HTTP request
MaxWait = TimeSpan.FromMinutes(5), // waiting for one queued job
Logger = loggerFactory.CreateLogger<Pdf4meClient>(),
});

在 ASP.NET Core 或任何使用依赖注入的应用程序,只需为整个应用程序注册一个客户端,并让日志记录器来自应用程序自身的日志记录设置即可:

builder.Services.AddSingleton(services => new Pdf4meClient(
builder.Configuration["Pdf4me:ApiKey"]!,
new Pdf4meClientOptions { Logger = services.GetRequiredService<ILogger<Pdf4meClient>>() }));

给客户一个 ILogger 从 Microsoft.Extensions.Logging 查看每个请求、响应、排队作业和轮询 Debug 等级。

如何在 C# 中处理长时间运行的任务和 OCR?​

每个操作都以异步任务的形式提交。无论服务器是立即响应还是将任务排队,并按照服务器设定的间隔轮询,调用都会返回最终结果。这很重要,原因有二:一是单个 await 可能会阻塞几分钟,而结束等待的原因是 MaxWait, 不是 Timeout。

  • Timeout 适用于 每个 HTTP 要求。
  • MaxWait 适用于 整个排队作业, 和 maxWait: 执行操作会覆盖该调用的默认行为。
  • 这 OCR 行动, ConvertOcrPdfAsync 和 ImageExtractTextAsync至少等待 10 分钟(DefaultOcrMaxWait),或者更长时间 MaxWait 更高。
using var cancel = new CancellationTokenSource(TimeSpan.FromMinutes(20));
byte[] searchable = await client.ConvertOcrPdfAsync(
File.ReadAllBytes("scan.pdf"), language: "English",
maxWait: TimeSpan.FromMinutes(20), cancellationToken: cancel.Token);

错误​

被拒绝或失败的请求会抛出异常。 Pdf4meException, 从 Pdf4me.Client.Generated.Models:

财产持有
Message这 API's 消息,否则响应正文将截断为 500 个字符,否则 HTTP 地位
ResponseStatusCode这 HTTP 状态码
TraceId这 API的跟踪 ID。报告问题时请引用它。
ResponseBody已发送的整个回复正文
ResponseHeaders响应头

等待时间结束后,仍在运行的任务会抛出异常。 TimeoutException无效参数(例如空文档)会抛出异常。 ArgumentException 在发送任何请求之前。

try
{
byte[] result = await client.OptimizeAsync(pdf);
}
catch (Pdf4meException e)
{
Console.Error.WriteLine($"PDF4me returned {e.ResponseStatusCode}: {e.Message} (trace {e.TraceId})");
}
catch (TimeoutException e)
{
Console.Error.WriteLine(e.Message);
}

18 个章节和全部 106 项操作​

操作按以下部分分组: PDF4me REST API 参考每个部分的各种方法都位于源代码中各自的文件中。有些方法所在的部分可能与名称不符: OCR 位于“查找搜索”中 PDF/A 创建过程在转换过程中,并且 MergeV3Async 是 PDF 而不是合并和拆分。

部分行动方法论 Pdf4meClient
AI 文档提取14AiDocumentParserAsync, ProcessBankChequeAsync, ProcessBankStatementAsync, ProcessContractAsync, ProcessCreditCardAsync, ProcessHealthCardAsync, ProcessInvoiceAsync, ProcessMarriageCertificateAsync, ProcessMortgageDocumentAsync, ProcessOrderAsync, ProcessPayStubAsync, ProcessReceiptAsync, ProcessShippingLabelAsync, ProcessTaxDocumentAsync
条形码7AddBarcodeAsync, CreateBarcodeAsync, CreateSwissQrBillAsync, ReadBarcodesAsync, ReadSwissQrBillAsync, CreateEpcQrCodeAsync, ReadBarcodesFromImageAsync
转变13ConvertHtmlToPdfAsync, ConvertJsonToExcelAsync, ConvertMdToPdfAsync, ConvertPdfToExcelAsync, ConvertPdfToPowerpointAsync, ConvertPdfToWordAsync, ConvertToPdfAsync, ConvertUrlToPdfAsync, ConvertVisioAsync, ConvertWordToPdfFormAsync, CreatePdfAAsync, FlattenPdfAsync, LinearizePdfAsync
编辑7AddAttachmentToPdfAsync, AddHtmlHeaderFooterAsync, ImageStampAsync, AddMarginAsync, AddPageNumberAsync, StampAsync, SignPdfAsync
Excel1FindAndReplaceTextInExcelAsync
提炼8ClassifyDocumentAsync, ExtractAttachmentFromPdfAsync, ExtractPdfFormDataAsync, ExtractResourcesAsync, ExtractTableFromPdfAsync, ExtractTextByExpressionAsync, ExtractTextFromWordAsync, ParseDocumentAsync
查找搜索2FindAndReplaceAsync, ConvertOcrPdfAsync
表格2AddFormFieldAsync, FillPdfFormAsync
产生6EnableTrackingChangesInWordAsync, GenerateDocumentSingleAsync, GenerateDocumentMultipleAsync, GetTrackingChangesInWordAsync, ReplaceTextWithImageInWordAsync, GenerateDocumentSingleV2Async
图像13AddImageWatermarkToImageAsync, AddTextWatermarkToImageAsync, CompressImageAsync, ConvertImageFormatAsync, CreateImagesAsync, CropImageAsync, FlipImageAsync, GetImageMetadataAsync, ImageExtractTextAsync, RemoveExifTagsFromImageAsync, ResizeImageAsync, RotateImageAsync, RotateImageByExifDataAsync
合并与拆分5MergeAsync, MergeOverlayAsync, SplitPdfAsync, SplitPdfByBarcodeAsync, SplitByTextAsync
优化1OptimizeAsync
组织5DeleteBlankPagesAsync, DeletePagesAsync, ExtractPagesAsync, RotateAsync, RotatePageAsync
PDF16MergeV3Async, GetPdfMetadataAsync, RepairPdfAsync, CreateHyperlinkAnnotationAsync, DeleteHyperlinkAnnotationAsync, DigitalSignPdfAsync, ExtractHyperlinkAnnotationAsync, GetDocumentByTextAsync, GetTextAndCoordinatesAsync, GetTextByPositionAsync, HighlightTextAsync, PrepareForPrintAsync, ReplaceTextWithImageAsync, ResizePdfAsync, SetPdfMetadataAsync, SignDocumentAsync
PDF4me1UpdateHyperlinkAnnotationAsync
安全2ProtectAsync, UnlockAsync
单词2DisableTrackingChangesInWordAsync, FindAndReplaceTextInWordAsync
ZUGFeRD1CreateZugferdInvoiceAsync

有关每个动作的参数和响应形状,请参阅 PDF4me REST API 参考或者将鼠标悬停在编辑器中的方法上:每个方法都带有与其文档页面相匹配的文档摘要。

从 1.x 版本迁移​

2.0 版本是对之前的版本进行了重写。 PDF4me API v2 版本以及 1.x 版本的所有功能都无法正常工作。标题已更改:

  • 它与……对话 API v2. 1.x 版本将 v1 版本的端点称为: /Optimize/OptimizeByProfile2.0 调用 /api/v2/...。
  • 单客户和按区域划分的客户都已不存在了。 Pdf4me.Instance.Init(token) 和 Pdf4me.Instance.OptimizeClient 合二为一 new Pdf4meClient(apiKey) 把每个动作都看作是它的方法。
  • 命名空间是 Pdf4me.Client, 不是 Pdf4meClient。
  • Newtonsoft.Json 不再是依赖项并且,1.x 版本引入的易受攻击的 12.0.3 版本也随之受到影响。
  • 错误是其中一种类型。 Pdf4meApiException 和 Pdf4meBackendException 变得 Pdf4meException。
  • .NET Framework 4.5.2 和 4.6.1 已不再受支持。 最低版本为 4.6.2,通过 .NET 标准 2.0。
1.x2.0
Pdf4me.Instance.Init(token)using var client = new Pdf4meClient(apiKey);
OptimizeClient.OptimizeByProfileAsync(file, profile)client.OptimizeAsync(file, profile: ...)
MergeClient.Merge2PdfsAsync(file1, file2)client.MergeAsync([file1, file2])
SplitClient.SplitByPageNrAsync(file, pageNr)client.SplitPdfAsync(file, splitActionNumber: pageNr)
ExtractClient.ExtractPagesAsync(file, pageNrs)client.ExtractPagesAsync(file, pageNumbers: pageNrs)
ConvertClient.ConvertFileToPdfAsync(file, fileName)client.ConvertToPdfAsync(file, docName: fileName)
PdfAClient.CreatePdfAAsync(file, compliance)client.CreatePdfAAsync(file, compliance: ...)
PdfAClient.RotateDocumentAsync(file, rotate)client.RotateAsync(file, rotationType: ...)
PdfAClient.ProtectDocumentAsync(file, password, perms)client.ProtectAsync(file, password: ..., pdfPermission: ...)
PdfAClient.UnlockDocumentAsync(file, password)client.UnlockAsync(file, password: ...)
PdfAClient.RepairDocumentAsync(file)client.RepairPdfAsync(file)
ImageClient.CreateThumbnailAsync(file, width, pageNr, fmt)client.CreateImagesAsync(file, new ImageAction { ... }, pageNrs: ...)

你的 API 密钥保持不变。更换 using Pdf4meClient; 和 using Pdf4me.Client;, 添加 using Pdf4me.Client.Generated.Models; 无论你使用选项或结果模型还是捕获 Pdf4meException然后逐一查看上面的表格。

故障排除​

TimeoutException 在一份大文件上。 这份工作比等待的时间更长,也就是说, MaxWait 默认值为 5 分钟,而不是 Timeout在电话会议上提出这个问题。 maxWait: TimeSpan.FromMinutes(20)或者,每次调用客户端时都如此。

一个 OCR 电话似乎卡住了十分钟。 这是有据可查的最低限度。 ConvertOcrPdfAsync 和 ImageExtractTextAsync 至少等一下 DefaultOcrMaxWait也就是10分钟,所以给他们自己的时间。 cancellationToken 如果来电者需要提前放弃。

401 Pdf4meException.ResponseStatusCode。 密钥存在但被拒绝。请在以下位置重新生成密钥: PDF4me 仪表板 并确认该变量对进程可见。在 Windows 系统上, set 不会跨会话持久化,因此请使用 setx 并打开一个新的终端。

ArgumentException 在任何内容到达网络之前。 本地检查失败,通常是文件为空,这意味着读取的文件返回了零字节。请检查文件路径,并确认文件未被其他进程锁定。

你传递了一个文件路径,但该文件没有任何反应。 字符串参数被视为 blob 引用或 https URL绝非本地路径。读取文件并传递其字节。

CreateThumbnailAsync 未找到。 1.x 版本的方法名称在 2.0 版本中已不存在。缩略图现在 CreateImagesAsync 一个 ImageAction请参阅迁移表。

模型或枚举类型出现编译错误。 选项对象和结果模型位于 Pdf4me.Client.Generated.Models虽然大多数枚举操作都在 Pdf4me.Client两者都导入。

常见问题​

PDF4me .NET SDK 是免费的吗?​

这 Pdf4me.Client 套餐免费 MIT 该软件包已获得许可,因此安装或重新分发均无需任何费用。该软件包是以下软件的客户端: PDF4me API这是一项托管服务,提供免费套餐和更高级别的付费套餐,因此文档处理会消耗资源。 API 您的账户将获得积分。您关联的代码本身不收取任何费用;处理费用是按流量计费的。

PDF4me .NET 客户端是开源的吗?​

是的。该客户已在以下平台发布: MIT 许可证及其来源位于 github.com/pdf4me/pdf4me-clientapi-dotnet如果您计划捐款,请注意以下事项: src/Pdf4me.Client/Generated/ 由……产生 Kiota 从 OpenAPI 描述会在每次重新生成时完全替换,因此如果该代码树中存在任何问题,请提交 issue,而不是直接打补丁。客户端及其周围的章节文件都是手工编写的,因此应该提交 pull request。

哪些 .NET 版本 Pdf4me.Client 支持?​

版本 2.0.0 目标 .NET 8、 .NET 9 和 .NET 10,加 .NET 标准 2.0,这意味着它也能运行在 .NET Framework 4.6.2 及更高版本。 .NET Framework 4.5.2 和 4.6.1 受 1.x 版本支持,但不受 2.0 版本支持。

如何在C#中将HTML转换为PDF?​

称呼 ConvertHtmlToPdfAsync 和 HTML 文件字节,或 ConvertUrlToPdfAsync 与一个 URL 将返回的字符串写入目标字符串。 byte[] 写入磁盘:

byte[] fromHtml = await client.ConvertHtmlToPdfAsync(File.ReadAllBytes("page.html"));
byte[] fromUrl = await client.ConvertUrlToPdfAsync("https://example.com");
File.WriteAllBytes("page.pdf", fromUrl);

渲染在服务端进行,因此无需安装、容器化或打补丁浏览器引擎,而这通常是使用本地库进行渲染的代价。

如何在C#中读取PDF文件?​

这取决于“阅读”的定义。 GetPdfMetadataAsync 返回一个 DocMetadata 以及页数和 PDF 版本。 ExtractTextByExpressionAsync, GetTextByPositionAsync 和 GetTextAndCoordinatesAsync 提取文本,最后一个包含位置信息。 ExtractTableFromPdfAsync 处理表格内容,并且 ConvertOcrPdfAsync 进行扫描 PDF 可搜索性优先。这些操作返回类型化的模型,而不是 byte[]。

我可以在不使用库的情况下用 C# 创建 PDF 文件吗?​

你可以写 PDF 手动进行字节格式转换,对于单页纯文本来说,这还算合理。但很快,这种方法就变得不合理了,因为字体、编码、压缩和交叉引用表都必须正确,而且读者对格式错误的容忍度也各不相同。实际上,选择在于使用本地渲染库并定期更新补丁,或者使用…… API 像这样的客户端,渲染是在服务器端进行的。 PDF 规范已发布。 ISO 32000-2 如果你想了解它的规模。

接下来该去哪里?​