html转pdf和图片
Go to file
zpc ecbeeabc1d
Some checks are pending
continuous-integration/drone/push Build is running
21
2026-04-05 14:22:45 +08:00
docs 21 2026-03-17 19:52:27 +08:00
mvp init 2025-12-11 23:35:52 +08:00
src ci: Add Drone CI/CD pipeline configuration and deployment documentation 2026-04-05 14:20:14 +08:00
.drone.yml 21 2026-04-05 14:22:45 +08:00
.gitignore init 2025-12-11 23:52:15 +08:00
CHANGELOG.md init 2025-12-11 23:52:15 +08:00
CI-CD部署文档.md ci: Add Drone CI/CD pipeline configuration and deployment documentation 2026-04-05 14:20:14 +08:00
CONTRIBUTING.md init 2025-12-11 23:52:15 +08:00
LICENSE init 2025-12-11 23:52:15 +08:00
README.md init 2025-12-11 23:52:15 +08:00

🎨 HtmlToPdf Service

高性能 HTML/URL 转 PDF/图片 微服务

基于 .NET 9 + PuppeteerSharp + Chromium 构建

.NET PuppeteerSharp Docker License

功能特性快速开始API 文档配置说明部署指南贡献指南


功能特性

核心转换能力

  • 🔄 HTML → PDF — 支持复杂 HTML 内容转换
  • 🌐 URL → PDF — 支持任意网页转换,完美渲染 SPAReact/Vue/Angular
  • 🖼️ HTML/URL → 图片 — 支持 PNG、JPEG、WebP 格式
  • 📐 自定义选项 — 纸张大小、方向、边距、页眉页脚等

高性能架构

  • 异步任务队列 — 基于 Redis 的任务队列,支持高并发
  • 🔧 浏览器池化 — 实例复用、自动重启、健康检查
  • 📦 批量处理 — 一次提交多个转换任务
  • 💾 结果缓存 — 相同内容避免重复转换

企业级安全

  • 🔐 API Key 认证 — 支持多租户 API Key 管理
  • 🛡️ 请求限流 — IP/用户维度的速率限制
  • 🚫 SSRF 防护 — 阻止内网地址访问
  • 🔑 幂等性支持 — Idempotency-Key 防止重复提交

运维友好

  • 📊 Prometheus 监控 — 完整的指标采集
  • 🏥 健康检查 — Ready/Live 探针,支持 K8s
  • 📝 结构化日志 — Serilog 日志输出
  • 🎛️ 管理后台 — Vue 3 构建的可视化管理界面

灵活存储

  • 💿 本地存储 — 适合单机部署
  • ☁️ 阿里云 OSS — 支持 CDN 加速
  • ☁️ 腾讯云 COS — 多云存储方案

📁 项目结构

html-to-pdf/
├── src/                            # 正式版源代码
│   ├── HtmlToPdfService.Api/       # Web API 层
│   ├── HtmlToPdfService.Core/      # 核心业务层
│   ├── HtmlToPdfService.Queue/     # 任务队列层
│   ├── HtmlToPdfService.Infrastructure/  # 基础设施层
│   ├── HtmlToPdfService.Admin/     # 管理后台Vue 3
│   ├── HtmlToPdfService.Tests/     # 测试项目
│   ├── docker-compose.yml          # Docker 编排文件
│   └── Dockerfile                  # Docker 构建文件
├── mvp/                            # MVP 简化版(同步模式)
├── docs/                           # 设计文档
└── README.md                       # 本文件

🚀 快速开始

方式一Docker Compose推荐

# 克隆项目
git clone https://github.com/your-username/html-to-pdf.git
cd html-to-pdf/src

# 启动服务
docker-compose up -d

# 查看日志
docker-compose logs -f htmltopdf

服务启动后访问:

方式二:本地开发

# 1. 启动 Redis
docker run -d --name redis -p 6379:6379 redis:7-alpine

# 2. 进入源码目录
cd src

# 3. 还原依赖
dotnet restore

# 4. 运行服务
dotnet run --project HtmlToPdfService.Api

方式三:使用 MVP 简化版

如果你只需要简单的同步转换功能,可以使用 MVP 版本:

cd mvp
docker-compose up -d

MVP vs 正式版对比:

  • MVP同步模式无需 Redis适合低并发场景
  • 正式版:异步队列,支持高并发、任务管理、监控告警

📖 API 接口

异步任务接口(推荐)

提交 PDF 转换任务

curl -X POST http://localhost:5000/api/tasks/pdf \
  -H "Content-Type: application/json" \
  -d '{
    "source": {
      "type": "html",
      "content": "<h1>Hello World</h1><p>这是测试内容</p>"
    },
    "options": {
      "format": "A4",
      "printBackground": true
    },
    "callback": {
      "url": "https://your-app.com/webhook"
    }
  }'

响应:

{
  "taskId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "pending",
  "message": "任务已创建,正在排队处理",
  "estimatedWaitTime": 3
}

查询任务状态

curl http://localhost:5000/api/tasks/{taskId}

下载结果文件

curl -O http://localhost:5000/api/tasks/{taskId}/download

提交图片转换任务

curl -X POST http://localhost:5000/api/tasks/image \
  -H "Content-Type: application/json" \
  -d '{
    "source": {
      "type": "url",
      "content": "https://www.example.com"
    },
    "options": {
      "format": "png",
      "fullPage": true,
      "width": 1920,
      "height": 1080
    }
  }'

批量提交任务

curl -X POST http://localhost:5000/api/tasks/batch \
  -H "Content-Type: application/json" \
  -d '{
    "tasks": [
      { "type": "pdf", "source": { "type": "html", "content": "<h1>Doc 1</h1>" } },
      { "type": "pdf", "source": { "type": "html", "content": "<h1>Doc 2</h1>" } }
    ]
  }'

同步接口MVP 兼容)

# HTML 转 PDF同步返回
curl -X POST http://localhost:5000/api/pdf/convert/html \
  -H "Content-Type: application/json" \
  -d '{"html": "<h1>Hello World</h1>"}' \
  -o document.pdf

# URL 转 PDF
curl -X POST http://localhost:5000/api/pdf/convert/url \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com"}' \
  -o document.pdf

系统接口

# 健康检查
curl http://localhost:5000/health

# 就绪探针K8s
curl http://localhost:5000/health/ready

# Prometheus 指标
curl http://localhost:5000/metrics

⚙️ 配置说明

主要配置在 appsettings.json 中:

{
  "PdfService": {
    "BrowserPool": {
      "MaxInstances": 10,
      "MinInstances": 2,
      "MaxConcurrent": 5,
      "MaxTasksPerBrowserInstance": 100,
      "BrowserRestartMemoryMb": 600
    },
    "TaskQueue": {
      "Type": "Redis",
      "Redis": {
        "ConnectionString": "localhost:6379"
      },
      "WorkerCount": 5
    },
    "Storage": {
      "Type": "Local",
      "LocalPath": "/app/files",
      "RetentionHours": 168
    },
    "Security": {
      "RequireAuthentication": false,
      "BlockPrivateNetworks": true
    },
    "RateLimit": {
      "Enabled": true,
      "RequestsPerMinutePerIp": 60
    }
  }
}

存储配置

本地存储(默认)
{
  "Storage": {
    "Type": "Local",
    "LocalPath": "/app/files",
    "RetentionHours": 168,
    "AutoCleanup": true
  }
}
阿里云 OSS
{
  "Storage": {
    "Type": "OSS",
    "OSS": {
      "Endpoint": "oss-cn-hangzhou.aliyuncs.com",
      "AccessKeyId": "your-access-key-id",
      "AccessKeySecret": "your-access-key-secret",
      "BucketName": "your-bucket-name",
      "PathPrefix": "htmltopdf",
      "UrlExpireSeconds": 3600
    }
  }
}
腾讯云 COS
{
  "Storage": {
    "Type": "COS",
    "COS": {
      "Region": "ap-guangzhou",
      "SecretId": "your-secret-id",
      "SecretKey": "your-secret-key",
      "BucketName": "your-bucket-1250000000",
      "PathPrefix": "htmltopdf",
      "UrlExpireSeconds": 3600
    }
  }
}

环境变量配置

所有配置都可以通过环境变量覆盖:

export PdfService__BrowserPool__MaxInstances=20
export PdfService__TaskQueue__Redis__ConnectionString=redis:6379
export PdfService__Security__RequireAuthentication=true

🐳 部署指南

Docker 单实例部署

cd src
docker-compose up -d

Kubernetes 部署

apiVersion: apps/v1
kind: Deployment
metadata:
  name: htmltopdf-service
spec:
  replicas: 3
  template:
    spec:
      containers:
      - name: htmltopdf
        image: htmltopdf-service:2.0
        resources:
          limits:
            memory: "2Gi"
            cpu: "2000m"
        env:
        - name: PdfService__TaskQueue__Redis__ConnectionString
          valueFrom:
            secretKeyRef:
              name: redis-secret
              key: connection-string

生产环境建议

资源 单实例 集群3实例
内存 2-4 GB 6-12 GB
CPU 2-4 核心 6-12 核心
并发能力 50+ QPS 150+ QPS

📊 监控与告警

Prometheus 指标

服务暴露 /metrics 端点,包含以下关键指标:

  • conversion_tasks_total - 转换任务总数
  • conversion_duration_seconds - 转换耗时分布
  • browser_pool_instances - 浏览器实例状态
  • task_queue_length - 队列长度

Grafana Dashboard

推荐监控面板:

  • 任务成功率
  • 平均处理时间
  • 队列积压情况
  • 浏览器池使用率

🛠️ 技术栈

组件 技术 版本
运行时 .NET 9.0
浏览器控制 PuppeteerSharp 20.x
渲染引擎 Chromium 自动下载
任务队列 Redis 7.0+
前端管理 Vue 3 + Element Plus 3.x
容器化 Docker 20.x
监控 Prometheus 2.40+

📈 性能指标

场景 吞吐量 响应时间
简单 HTML → PDF 100+ QPS < 3s
复杂 HTML → PDF 50+ QPS < 10s
URL → PDF 30+ QPS < 15s
HTML → 图片 150+ QPS < 2s

🤝 贡献

欢迎提交 Issue 和 Pull Request

  1. Fork 本仓库
  2. 创建功能分支 (git checkout -b feature/AmazingFeature)
  3. 提交更改 (git commit -m 'Add some AmazingFeature')
  4. 推送到分支 (git push origin feature/AmazingFeature)
  5. 提交 Pull Request

📄 许可证

本项目采用 MIT 许可证 开源。


📞 联系方式


如果这个项目对你有帮助,请给一个 Star

Made with ❤️ by the HtmlToPdf Team