# HtmlToPdfService.Client HTML 转 PDF/图片服务的 .NET 客户端库,支持依赖注入。 ## 安装 ```bash dotnet add package HtmlToPdfService.Client ``` ## 快速开始 ### 方式一:依赖注入(推荐) ```csharp // Program.cs using HtmlToPdfService.Client.Extensions; var builder = WebApplication.CreateBuilder(args); // 添加客户端服务 builder.Services.AddHtmlToPdfClient(options => { options.BaseUrl = "https://pdf-service.example.com"; options.ApiKey = "your-api-key"; // 可选 options.EnableRetry = true; // 可选,启用重试 }); var app = builder.Build(); ``` ```csharp // 使用服务 public class MyService { private readonly IHtmlToPdfClient _pdfClient; public MyService(IHtmlToPdfClient pdfClient) { _pdfClient = pdfClient; } public async Task GeneratePdfAsync() { return await _pdfClient.ConvertHtmlToPdfAsync("

Hello World

"); } } ``` ### 方式二:从配置文件读取 ```json // appsettings.json { "HtmlToPdfClient": { "BaseUrl": "https://pdf-service.example.com", "ApiKey": "your-api-key", "TimeoutSeconds": 120, "EnableRetry": true, "RetryCount": 3 } } ``` ```csharp // Program.cs builder.Services.AddHtmlToPdfClient(builder.Configuration); ``` ### 方式三:多服务器配置(命名客户端) ```csharp // 注册多个命名客户端 builder.Services.AddHtmlToPdfClient("production", options => { options.BaseUrl = "https://pdf-prod.example.com"; options.ApiKey = "prod-api-key"; }); builder.Services.AddHtmlToPdfClient("staging", options => { options.BaseUrl = "https://pdf-staging.example.com"; options.ApiKey = "staging-api-key"; }); ``` ```csharp // 使用工厂创建指定客户端 public class MyService { private readonly IHtmlToPdfClientFactory _factory; public MyService(IHtmlToPdfClientFactory factory) { _factory = factory; } public async Task GeneratePdfAsync(bool useProduction) { var clientName = useProduction ? "production" : "staging"; var client = _factory.CreateClient(clientName); return await client.ConvertHtmlToPdfAsync("

Hello

"); } } ``` ### 方式四:直接实例化 ```csharp using HtmlToPdfService.Client; using Microsoft.Extensions.Options; var options = new HtmlToPdfClientOptions { BaseUrl = "https://pdf-service.example.com", ApiKey = "your-api-key" }; using var httpClient = new HttpClient(); var client = new HtmlToPdfClient(httpClient, Options.Create(options)); var pdf = await client.ConvertHtmlToPdfAsync("

Hello

"); ``` ## 功能示例 ### 同步 PDF 转换 ```csharp // HTML 转 PDF var pdf = await client.ConvertHtmlToPdfAsync( html: "

Hello

", options: new PdfOptions { Format = "A4", Landscape = false, PrintBackground = true, Margin = new MarginOptions { Top = "10mm", Right = "10mm", Bottom = "10mm", Left = "10mm" } }); // URL 转 PDF var pdf = await client.ConvertUrlToPdfAsync( url: "https://example.com", waitUntil: "networkidle0", timeout: 30); ``` ### 同步图片转换 ```csharp // HTML 转图片 var image = await client.ConvertHtmlToImageAsync( html: "

Hello

", options: new ImageOptions { Format = "png", Width = 1920, Height = 1080, FullPage = true }); // URL 转图片 var image = await client.ConvertUrlToImageAsync( url: "https://example.com", options: new ImageOptions { Format = "jpeg", Quality = 90 }); ``` ### 异步任务 ```csharp // 提交 PDF 任务 var result = await client.SubmitPdfTaskAsync( source: new SourceInfo { Type = "html", Content = "

Hello

" }, options: new PdfOptions { Format = "A4" }, callback: new CallbackInfo { Url = "https://my-app.com/callback" }); Console.WriteLine($"任务 ID: {result.TaskId}"); Console.WriteLine($"队列位置: {result.QueuePosition}"); // 查询任务状态 var status = await client.GetTaskStatusAsync(result.TaskId); Console.WriteLine($"状态: {status.Status}"); // 等待任务完成并下载 var pdf = await client.WaitAndDownloadAsync(result.TaskId); ``` ### 批量任务 ```csharp var tasks = new List { new BatchTaskInput { Type = "pdf", Source = new SourceInfo { Type = "html", Content = "

Doc 1

" } }, new BatchTaskInput { Type = "image", Source = new SourceInfo { Type = "url", Content = "https://example.com" }, ImageOptions = new ImageOptions { Format = "png" } } }; var batch = await client.SubmitBatchAsync(tasks); Console.WriteLine($"批量任务 ID: {batch.BatchId}"); // 查询批量任务状态 var batchStatus = await client.GetBatchStatusAsync(batch.BatchId); Console.WriteLine($"已完成: {batchStatus.CompletedTasks}/{batchStatus.TotalTasks}"); ``` ### 任务管理 ```csharp // 查询任务列表 var list = await client.QueryTasksAsync( status: "completed", type: "pdf", page: 1, pageSize: 20); // 取消任务 await client.CancelTaskAsync(taskId); // 重试失败的任务 await client.RetryTaskAsync(taskId); ``` ## 配置选项 | 选项 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `BaseUrl` | string | - | 服务端地址(必填) | | `ApiKey` | string | null | API Key(可选) | | `TimeoutSeconds` | int | 120 | 请求超时时间 | | `EnableRetry` | bool | false | 是否启用重试 | | `RetryCount` | int | 3 | 重试次数 | | `RetryBaseDelayMs` | int | 500 | 重试基础延迟(指数退避) | | `CustomHeaders` | Dictionary | null | 自定义请求头 | ## 异常处理 ```csharp using HtmlToPdfService.Client.Exceptions; try { var pdf = await client.ConvertHtmlToPdfAsync("

Hello

"); } catch (ValidationException ex) { // 参数验证失败 (400) Console.WriteLine($"参数错误: {ex.Message}"); } catch (AuthenticationException ex) { // 认证失败 (401) Console.WriteLine($"认证失败: {ex.Message}"); } catch (TaskNotFoundException ex) { // 任务不存在 (404) Console.WriteLine($"任务不存在: {ex.TaskId}"); } catch (TaskConflictException ex) { // 任务状态冲突 (409) Console.WriteLine($"任务状态: {ex.CurrentStatus}"); } catch (ServiceUnavailableException ex) { // 服务不可用 (503) Console.WriteLine($"服务繁忙: {ex.Message}"); } catch (HtmlToPdfClientException ex) { // 其他错误 Console.WriteLine($"错误: {ex.Message}, 状态码: {ex.StatusCode}"); } ``` ## 支持的框架 - .NET 8.0 - .NET Standard 2.0(兼容 .NET Framework 4.6.1+、.NET Core 2.0+ 等) ## License MIT