npm package: @neosjs/html-to-pdf
Description: 高性能HTML转PDF工具，支持中文、图片、表格、分页、水印、自定义页眉页脚和页码，内置性能监控和错误处理
Author: 听着情歌流泪
Latest version: 2.3.1-alpha-1

<div align="center">

# HTML 转 PDF 工具库

</div>

一个功能强大、简单易用、高性能的 HTML 转 PDF 工具，支持中文、图片、表格、分页、水印、加密、自定义边距、自定义页眉页脚和页码，内置性能监控和错误处理。  
完善的 TypeScript 支持。

<div align="center">

![NPM Version][npm-version-image] ![Npm Month Downloads][npm-downloads-image-month] ![Node Version][node-current] ![License][license-image] ![html-to-pdf][html-to-pdf]

</div>

## ✨ 特性

- 🎯 **简单易用**: 简洁的 API 设计，几行代码即可生成 PDF
- 🚀 **高性能**: 优化图片处理和内存管理
- 📄 **完整分页**: 智能内容分页，支持页眉页脚
- 🎨 **自定义样式**: 支持自定义页眉、页脚、页码样式、PDF 边距、背景色
- 📊 **性能监控**: 内置性能监控和错误追踪
- 🖼️ **图片支持**: 支持图片、表格、复杂布局
- 🇨🇳 **中文支持**: 完美支持中文字体和排版
- 📏 **边距控制**: 灵活的页面边距配置
- 🪓 **TypeScript**: 完整的 TypeScript 类型支持
- 🎯 **精确控制**: 支持自定义纸张大小和方向
- 🔧 **高度可配置**: 丰富的配置选项满足各种需求
- 🔐 **支持加密**: 自定义打开 PDF 的权限
- 📜 **防泄密**: 支持自定义水印

## 📦 安装

```bash
# 使用 pnpm (推荐)
pnpm add @neosjs/html-to-pdf

# 使用 npm
npm install @neosjs/html-to-pdf

# 使用 yarn
yarn add @neosjs/html-to-pdf
```

## 🚀 快速开始

### 基础用法

```typescript
import { generatePDF } from "@neosjs/html-to-pdf";

// 获取要转换的DOM元素
const contentElement = document.getElementById("content");

// 生成PDF
const { blob, pdf } = await generatePDF({
  contentDom: contentElement,
  paperSize: "a4",
  orientation: "p",
});

// 下载PDF
pdf.save("document.pdf");
```

### 高级用法

```typescript
import { generatePDF, LogLevel } from '@neosjs/html-to-pdf'

const { blob, pdf } = await generatePDF({
  // 内容DOM
  contentDom: document.getElementById('content'),

  // 封面DOM (可选)
  coverDom: document.getElementById('cover'),

  // PDF背景色
  backgroundColor: '#FFFFFF',

  // 页面配置
  paperSize: 'a4',
  orientation: 'p',

  // 边距配置
  margins: {
    top: 20,
    bottom: 20,
    left: 20,
    right: 20,
    enabled: true
  },

  // 页眉配置
  header: {
    content: '文档',
    fontSize: 14,
    fontColor: '#333',
    position: 'center',
    border: true,
    padding: 10
  },

  // 页脚配置
  footer: {
    content: '机密文件',
    fontSize: 12,
    fontColor: '#666',
    position: 'left',
    border: false,
    padding: 8
  },

  // 页码配置
  pageNumber: {
    enabled: true,
    fontSize: 12
  },

  // 配置插件列表
  plugins:[{
    name: 'watermark', // 插件名称
    // 单个插件配置
    config: {
      text: '水印文件',
      fontSize: 12,
      color: '#ddd',
      opacity: 0.5,
      rotation: 30,
      repeat: true, // 启用重复
      repeatMode: 'grid', // 网格模式
    },
    enabled: false // 是否启用插件
  }],

  // 加密设置
  encryption:{
    userPassword: '123456', // 用户打开PDF文件的密码
    ownerPassword: '654321' // PDF拥有者打开文件的密码
    userPermissions: 'print' // 'print' | 'modify' | 'copy' | 'annot-forms'
  },

  // 性能监控
  performanceConfig: {
    enablePerformanceMonitoring: true,
    enableMemoryMonitoring: true,
    performanceThreshold: {
      screenshotTime: 5000,
      pdfGenerationTime: 10000,
      memoryUsage: 100
    }
  },

  // 质量优化配置
  optimizationConfig: {
    scale: 1.5, //pdf比例，值越大越清晰，但，同时也比较消耗性能 (默认：1.5)
    quality: 0.8,
    usePngFormat: true,
    enableAntialiasing: true,
    enableHighPrecision: true
  },

  // 日志回调
  logCallback: (log) => {
    console.log(`[${log.level}] ${log.message}`, log.data)
  }
})
```

## 📚 API 文档

### generatePDF(config: PdfOptions)

生成 PDF 的主函数。

#### 参数

#### contentDom: HTMLElement

要转换为 PDF 的 DOM 元素（必需）

#### coverDom?: HTMLElement

封面页 DOM 元素（可选）

#### paperSize?: PaperSize

纸张大小，默认为 'a4'

- `'a0'` - A0
- `'a1'` - A1
- `'a2'` - A2
- `'a3'` - A3
- `'a4'` - A4
- `'a5'` - A5
- `'a6'` - A6
- `'a7'` - A7
- `'a8'` - A8

#### orientation?: PageOrientation

页面方向，默认为 'p'

- `'p'` - 竖版
- `'l'` - 横版

#### optimizationConfig?: OptimizationConfig

质量优化配置

```typescript
interface OptimizationConfig {
  /** 缩放 (默认: 1.5) */
  scale?: number;
  /** 图片质量 */
  quality?: number;
  /** 是否使用PNG格式 (默认: true，避免JPEG压缩损失) */
  usePngFormat?: boolean;
  /** PNG压缩级别 (0-9, 0=无压缩, 9=最大压缩, 默认: 0) */
  pngCompressionLevel?: number;
  /** 是否启用抗锯齿 (默认: true) */
  enableAntialiasing?: boolean;
  /** 是否启用高精度绘制 (默认: true) */
  enableHighPrecision?: boolean;
}
```

#### margins?: MarginConfig

页面边距配置

```typescript
interface MarginConfig {
  top?: number; // 上边距 (默认: 0px)
  bottom?: number; // 下边距 (默认: 10px)
  left?: number; // 左边距 (默认: 30px)
  right?: number; // 右边距 (默认: 30px)
  enabled?: boolean; // 是否启用边距 (默认: true)
}
```

#### header?: HeaderConfig

页眉配置

```typescript
interface HeaderConfig {
  content?: string; // 页眉内容
  fontSize?: number; // 字体大小 (默认: 12px)
  fontColor?: string; // 字体颜色 (默认: #dddddd)
  fontFamily?: string;
  fontWeight?:
    | "normal"
    | "bold"
    | "bolder"
    | "lighter"
    | "100"
    | "200"
    | "300"
    | "400"
    | "500"
    | "600"
    | "700"
    | "800"
    | "900"; // 字体粗细 (默认: normal)
  fontStyle?: "normal" | "italic" | "oblique"; // 字体样式 (默认: normal)
  fontColor?: string; // 字体颜色 (默认: #dddddd)
  fontFamily?: string; // 字体族 (默认: Microsoft YaHei)
  position?: "left" | "center" | "right"; // 位置 (默认: center)
  border?: boolean; // 是否显示边框 (默认: false)
  borderHeight?: number; // 边框高度 (默认： 1px)
  height?: number; // 页眉高度
  autoHeight?: boolean; // 是否自动计算高度 (默认: true)
  minHeight?: number; // 最小高度 (默认: 40px)
  maxHeight?: number; // 最大高度 (默认: 60px)
  padding?: number; // 内边距 (默认: 8px)
}
```

#### footer?: FooterConfig

页脚配置（与页眉配置结构相同）

#### pageNumber?: PageNumberConfig

页码配置

```typescript
interface PageNumberConfig {
  fontSize?: number; // 字体大小 (默认: 12px)
  fontWeight:
    | "normal"
    | "bold"
    | "bolder"
    | "lighter"
    | "100"
    | "200"
    | "300"
    | "400"
    | "500"
    | "600"
    | "700"
    | "800"
    | "900";
  fontStyle: "normal" | "italic" | "oblique";
  fontColor: string; // 字体颜色 (默认: #dddddd)
  enabled: boolean; // 是否显示页码 (默认: true)
}
```

#### encryption?: EncryptionConfig

加密配置

```typescript
interface EncryptionConfig {
  userPassword?: string;
  ownerPassword?: string;
  userPermissions?: ("print" | "modify" | "copy" | "annot-forms")[];
}
```

#### performanceConfig?: PerformanceConfig

性能监控配置

```typescript
interface PerformanceConfig {
  enablePerformanceMonitoring?: boolean;
  enableMemoryMonitoring?: boolean;
  enableErrorTracking?: boolean;
  performanceThreshold?: {
    screenshotTime?: number; // 截图时间阈值(ms)
    pdfGenerationTime?: number; // PDF生成时间阈值(ms)
    memoryUsage?: number; // 内存使用阈值(MB)
  };
}
```

#### logCallback?: (log: LogData) => void

日志回调函数

```typescript
interface LogData {
  level: LogLevel;
  message: string;
  timestamp: number;
  data?: any;
  error?: Error;
}
```

#### 返回值

```typescript
{
  blob: Blob,    // PDF文件的Blob对象
  pdf: JsPDF     // JsPDF实例，可用于进一步操作
}
```

### 工具函数

#### getPageDimensions(paperSize: PaperSize, orientation: PageOrientation)

获取纸张尺寸信息

#### clearCache()

清理图片缓存

#### getCacheStatistics()

获取缓存统计信息

#### createPerformanceMonitor(config?: any)

创建性能监控器实例

## 📝 示例

### 基础示例

```html
<!DOCTYPE html>
<html>
  <head>
    <title>基础示例</title>
  </head>
  <body>
    <div id="content">
      <h1>测试文档</h1>
      <p>这是一个测试文档的内容...</p>
    </div>

    <button onclick="generatePDF()">生成PDF</button>

    <script type="module">
      import HtmlToPdf from "@neosjs/html-to-pdf";
      const generatePDF = new HtmlToPdf();

      async function handleGeneratePDF() {
        try {
          const content = document.getElementById("content");
          const { blob, pdf } = await generatePDF.generatePDF({
            contentDom: content,
            paperSize: "a4",
            orientation: "p",
          });

          // 下载PDF
          pdf.save("document.pdf");
        } catch (error) {
          console.error("PDF生成失败:", error);
        }
      }

      window.generatePDF = generatePDF;
    </script>
  </body>
</html>
```

### 带页眉页脚的示例

```typescript
const { blob } = await generatePDF({
  contentDom: document.getElementById("content"),
  paperSize: "a4",
  orientation: "p",

  // 页眉
  header: {
    content: "公司文档",
    fontSize: 14,
    fontColor: "#333",
    position: "center",
    border: true,
  },

  // 页脚
  footer: {
    content: "机密文件",
    fontSize: 12,
    fontColor: "#666",
    position: "left",
  },

  // 页码
  pageNumber: {
    enabled: true,
    fontSize: 12,
  },

  // 边距
  margins: {
    top: 30,
    bottom: 30,
    left: 25,
    right: 25,
    enabled: true,
  },
});
```

### 性能监控示例

```typescript
const { blob } = await generatePDF({
  contentDom: document.getElementById("content"),

  // 性能监控
  performanceConfig: {
    enablePerformanceMonitoring: true,
    enableMemoryMonitoring: true,
    performanceThreshold: {
      screenshotTime: 5000,
      pdfGenerationTime: 10000,
      memoryUsage: 100,
    },
  },

  // 日志回调
  logCallback: (log) => {
    switch (log.level) {
      case "info":
        console.log(`✅ ${log.message}`, log.data);
        break;
      case "warn":
        console.warn(`⚠️ ${log.message}`, log.data);
        break;
      case "error":
        console.error(`❌ ${log.message}`, log.error);
        break;
    }
  },
});
```

## 📄 License

[MIT](./LICENSE) License &copy; 2021 - PRESENT [NeosJS](https://docs.neosjs.com/)

[npm-version-image]: https://img.shields.io/npm/v/@neosjs/html-to-pdf?style=flat&colorA=2d333b&colorB=1fa669
[npm-downloads-image-month]: https://img.shields.io/npm/dm/@neosjs/html-to-pdf?style=flat&colorA=2d333b&colorB=1fa669
[license-image]: https://img.shields.io/npm/l/@neosjs/html-to-pdf?style=flat&colorA=2d333b&colorB=1fa669
[html-to-pdf]: https://img.shields.io/badge/NeosJS-html--to--pdf-1fa669?style=flat&colorA=2d333b&colorB=1fa669
[node-current]: https://img.shields.io/node/v/@neosjs/html-to-pdf?style=flat&colorA=2d333b&colorB=1fa669

## 🙏 致谢

- [jsPDF](https://github.com/parallax/jsPDF) - PDF 生成库
- [html-to-image](https://github.com/bubkoo/html-to-image) - HTML 转图片库