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) |
| 根据 URL | https://api.pdf4me.com |
| 来源 | github.com/pdf4me/pdf4me-clientapi-dotnet |
| NuGet | nuget.org/packages/Pdf4me.Client |
先决条件
- .NET 8 或更新版本,或 .NET 框架 4.6.2 或更高版本 .NET 标准 2.0。
- A PDF4me 账户和 API 钥匙。
安装
- dotnet CLI
- Package Manager
- PackageReference
dotnet add package Pdf4me.Client
NuGet\Install-Package Pdf4me.Client -Version 2.0.0
<PackageReference Include="Pdf4me.Client" Version="2.0.0" />
认证
设置你的 API 环境中的关键因素:
- Bash / Zsh
- PowerShell
- Windows CMD
export PDF4ME_API_KEY="your-api-key"
$env:PDF4ME_API_KEY = "your-api-key"
set 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 文档提取 | 14 | AiDocumentParserAsync, ProcessBankChequeAsync, ProcessBankStatementAsync, ProcessContractAsync, ProcessCreditCardAsync, ProcessHealthCardAsync, ProcessInvoiceAsync, ProcessMarriageCertificateAsync, ProcessMortgageDocumentAsync, ProcessOrderAsync, ProcessPayStubAsync, ProcessReceiptAsync, ProcessShippingLabelAsync, ProcessTaxDocumentAsync |
| 条形码 | 7 | AddBarcodeAsync, CreateBarcodeAsync, CreateSwissQrBillAsync, ReadBarcodesAsync, ReadSwissQrBillAsync, CreateEpcQrCodeAsync, ReadBarcodesFromImageAsync |
| 转变 | 13 | ConvertHtmlToPdfAsync, ConvertJsonToExcelAsync, ConvertMdToPdfAsync, ConvertPdfToExcelAsync, ConvertPdfToPowerpointAsync, ConvertPdfToWordAsync, ConvertToPdfAsync, ConvertUrlToPdfAsync, ConvertVisioAsync, ConvertWordToPdfFormAsync, CreatePdfAAsync, FlattenPdfAsync, LinearizePdfAsync |
| 编辑 | 7 | AddAttachmentToPdfAsync, AddHtmlHeaderFooterAsync, ImageStampAsync, AddMarginAsync, AddPageNumberAsync, StampAsync, SignPdfAsync |
| Excel | 1 | FindAndReplaceTextInExcelAsync |
| 提炼 | 8 | ClassifyDocumentAsync, ExtractAttachmentFromPdfAsync, ExtractPdfFormDataAsync, ExtractResourcesAsync, ExtractTableFromPdfAsync, ExtractTextByExpressionAsync, ExtractTextFromWordAsync, ParseDocumentAsync |
| 查找搜索 | 2 | FindAndReplaceAsync, ConvertOcrPdfAsync |
| 表格 | 2 | AddFormFieldAsync, FillPdfFormAsync |
| 产生 | 6 | EnableTrackingChangesInWordAsync, GenerateDocumentSingleAsync, GenerateDocumentMultipleAsync, GetTrackingChangesInWordAsync, ReplaceTextWithImageInWordAsync, GenerateDocumentSingleV2Async |
| 图像 | 13 | AddImageWatermarkToImageAsync, AddTextWatermarkToImageAsync, CompressImageAsync, ConvertImageFormatAsync, CreateImagesAsync, CropImageAsync, FlipImageAsync, GetImageMetadataAsync, ImageExtractTextAsync, RemoveExifTagsFromImageAsync, ResizeImageAsync, RotateImageAsync, RotateImageByExifDataAsync |
| 合并与拆分 | 5 | MergeAsync, MergeOverlayAsync, SplitPdfAsync, SplitPdfByBarcodeAsync, SplitByTextAsync |
| 优化 | 1 | OptimizeAsync |
| 组织 | 5 | DeleteBlankPagesAsync, DeletePagesAsync, ExtractPagesAsync, RotateAsync, RotatePageAsync |
| 16 | MergeV3Async, GetPdfMetadataAsync, RepairPdfAsync, CreateHyperlinkAnnotationAsync, DeleteHyperlinkAnnotationAsync, DigitalSignPdfAsync, ExtractHyperlinkAnnotationAsync, GetDocumentByTextAsync, GetTextAndCoordinatesAsync, GetTextByPositionAsync, HighlightTextAsync, PrepareForPrintAsync, ReplaceTextWithImageAsync, ResizePdfAsync, SetPdfMetadataAsync, SignDocumentAsync | |
| PDF4me | 1 | UpdateHyperlinkAnnotationAsync |
| 安全 | 2 | ProtectAsync, UnlockAsync |
| 单词 | 2 | DisableTrackingChangesInWordAsync, FindAndReplaceTextInWordAsync |
| ZUGFeRD | 1 | CreateZugferdInvoiceAsync |
有关每个动作的参数和响应形状,请参阅 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.x | 2.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 如果你想了解它的规模。