Skip to content

PDFcpu API 使用指南

简介

PDFcpu是一个用Go语言编写的PDF处理工具库,提供了丰富的PDF文件操作功能。本文档将介绍pdfcpu的主要API及其使用方法。

主要功能

1. 验证PDF文件

go
// 验证PDF文件
api.Validate("in.pdf", nil)

// 使用配置选项验证PDF文件
api.ValidateFile("in.pdf", conf)

2. 优化PDF文件

go
// 优化PDF文件
api.Optimize("in.pdf", "out.pdf", nil)

// 使用配置选项优化PDF文件
api.OptimizeFile("in.pdf", "out.pdf", conf)

3. 加密和解密

go
// 加密PDF文件(基于Reader/Writer)
api.Encrypt(rs io.ReadSeeker, w io.Writer, conf *model.Configuration) error

// 加密PDF文件(基于文件路径)
api.EncryptFile(inFile, outFile string, conf *model.Configuration) error

// 解密PDF文件(基于Reader/Writer)
api.Decrypt(rs io.ReadSeeker, w io.Writer, conf *model.Configuration) error

// 解密PDF文件(基于文件路径)
api.DecryptFile(inFile, outFile string, conf *model.Configuration) error

// 获取PDF文件权限
api.GetPermissions(rs io.ReadSeeker, conf *model.Configuration) (*int16, error)
api.GetPermissionsFile(inFile string, conf *model.Configuration) (*int16, error)

4. 书签和元数据操作

go
// 导出书签到JSON
api.ExportBookmarksJSON(rs io.ReadSeeker, w io.Writer, source string, conf *model.Configuration) error
api.ExportBookmarksFile(inFilePDF, outFileJSON string, conf *model.Configuration) error

// 导入书签
api.ImportBookmarks(rs io.ReadSeeker, rd io.Reader, w io.Writer, replace bool, conf *model.Configuration) error
api.ImportBookmarksFile(inFilePDF, inFileJSON, outFilePDF string, replace bool, conf *model.Configuration) error

// 导出元数据
api.ExtractMetadata(rs io.ReadSeeker, outDir, fileName string, conf *model.Configuration) error
api.ExtractMetadataFile(inFile, outDir string, conf *model.Configuration) error

5. 表单操作

go
// 导出表单
api.ExportForm(rs io.ReadSeeker, source string, conf *model.Configuration) (*form.FormGroup, error)
api.ExportFormFile(inFilePDF, outFileJSON string, conf *model.Configuration) error
api.ExportFormJSON(rs io.ReadSeeker, w io.Writer, source string, conf *model.Configuration) error

// 填充表单
api.FillForm(rs io.ReadSeeker, rd io.Reader, w io.Writer, conf *model.Configuration) error
api.FillFormFile(inFilePDF, inFileJSON, outFilePDF string, conf *model.Configuration) error

// 获取表单字段
api.FormFields(rs io.ReadSeeker, conf *model.Configuration) ([]form.Field, error)

// 锁定表单字段
api.LockFormFields(rs io.ReadSeeker, w io.Writer, fieldIDsOrNames []string, conf *model.Configuration) error
api.LockFormFieldsFile(inFile, outFile string, fieldIDsOrNames []string, conf *model.Configuration) error

6. 内容提取

go
// 提取页面内容
api.ExtractContent(rs io.ReadSeeker, outDir, fileName string, selectedPages []string, conf *model.Configuration) error
api.ExtractContentFile(inFile, outDir string, selectedPages []string, conf *model.Configuration) error

// 提取字体
api.ExtractFonts(rs io.ReadSeeker, outDir, fileName string, selectedPages []string, conf *model.Configuration) error
api.ExtractFontsFile(inFile, outDir string, selectedPages []string, conf *model.Configuration) error

// 提取图片
api.ExtractImages(rs io.ReadSeeker, selectedPages []string, conf *model.Configuration) error
api.ExtractImagesFile(inFile, outDir string, selectedPages []string, conf *model.Configuration) error
api.ExtractImagesRaw(rs io.ReadSeeker, selectedPages []string, conf *model.Configuration) ([]map[int]model.Image, error)

// 提取单个页面
api.ExtractPage(ctx *model.Context, pageNr int) (io.Reader, error)

// 提取多个页面
api.ExtractPages(rs io.ReadSeeker, outDir, fileName string, selectedPages []string, conf *model.Configuration) error
api.ExtractPagesFile(inFile, outDir string, selectedPages []string, conf *model.Configuration) error

7. 附件操作

go
// 提取附件
api.ExtractAttachments(rs io.ReadSeeker, outDir string, fileNames []string, conf *model.Configuration) error
api.ExtractAttachmentsFile(inFile, outDir string, files []string, conf *model.Configuration) error
api.ExtractAttachmentsRaw(rs io.ReadSeeker, outDir string, fileNames []string, conf *model.Configuration) ([]model.Attachment, error)

8. 图像处理

go
// 获取图像信息
api.Images(rs io.ReadSeeker, selectedPages []string, conf *model.Configuration) ([]map[int]model.Image, error)

// 导入图像
api.ImportImages(rs io.ReadSeeker, w io.Writer, imgs []io.Reader, imp *pdfcpu.Import, conf *model.Configuration) error
api.ImportImagesFile(imgFiles []string, outFile string, imp *pdfcpu.Import, conf *model.Configuration) error

// 图像布局配置
api.ImageBookletConfig(val int, desc string, conf *model.Configuration) (*model.NUp, error)
api.ImageGridConfig(rows, cols int, desc string, conf *model.Configuration) (*model.NUp, error)
api.ImageNUpConfig(val int, desc string, conf *model.Configuration) (*model.NUp, error)

// 图像水印
api.ImageWatermark(fileName, desc string, onTop, update bool, u types.DisplayUnit) (*model.Watermark, error)
api.ImageWatermarkForReader(r io.Reader, desc string, onTop, update bool, u types.DisplayUnit) (*model.Watermark, error)

9. 配置管理

go
// 配置目录操作
api.DisableConfigDir()
api.EnsureDefaultConfigAt(path string) error

// 加载配置
api.LoadConfiguration() *model.Configuration

// 字体管理
api.InstallFonts(fileNames []string) error
api.ListFonts() ([]string, error)

// 证书管理
api.ImportCertificates(inFiles []string) ([]string, error)
api.LoadCertificates() (int, error)

10. 页面操作

go
// 合并多个PDF文件
api.MergeFile([]string{"file1.pdf", "file2.pdf"}, "merged.pdf", nil)

// 高级合并操作
api.MergeAppendFile(inFiles, outFile, dividerPage, conf)  // 追加合并
api.MergeCreateFile(inFiles, outFile, dividerPage, conf)   // 创建新文件合并
api.MergeCreateZipFile(inFile1, inFile2, outFile, conf)   // 合并并压缩
api.MergeRaw(rsc []io.ReadSeeker, w io.Writer, dividerPage, conf) // 原始数据合并

// 分割PDF文件
api.Split("in.pdf", "outPrefix", 1, nil)

// 提取特定页面
api.ExtractPages("in.pdf", "out.pdf", []string{"1-3"}, nil)

// 旋转页面
api.RotateFile("in.pdf", "out.pdf", 90, nil, nil)

// 裁剪页面
api.Crop("in.pdf", "out.pdf", "0 0 500 800", nil)

// 调整页面尺寸
api.Resize("in.pdf", "out.pdf", "A4", nil)

// 导入页面
api.ImportPages("in1.pdf", "in2.pdf", []string{"1-3"}, "out.pdf", nil)

// 页面布局和模式
api.PageLayout(rs, conf)      // 获取页面布局
api.PageLayoutFile(inFile, conf) // 获取文件页面布局
api.PageMode(rs, conf)        // 获取页面模式
api.PageModeFile(inFile, conf)   // 获取文件页面模式

// 页面信息
api.PageCount(rs, conf)       // 获取页面总数
api.PageCountFile(inFile)     // 获取文件页面总数
api.PageDims(rs, conf)        // 获取页面尺寸
api.PageDimsFile(inFile)      // 获取文件页面尺寸

// 页面选择和范围
api.PagesForPageCollection(pageCount, pageSelection)   // 页面集合
api.PagesForPageRange(from, thru)                    // 页面范围
api.PagesForPageSelection(pageCount, pageSelection, ensureAllforNone, log) // 页面选择
api.ParsePageSelection(s)                           // 解析页面选择

// 多页面处理
api.NDown(rs, outDir, fileName, selectedPages, n, conf)  // N页下移
api.NDownFile(inFile, outDir, outFile, selectedPages, n, cut, conf) // N页下移到文件
api.NUp(rs, w, imgFiles, selectedPages, nup, conf)      // N页合一
api.NUpFile(inFiles, outFile, selectedPages, nup, conf) // N页合一到文件

// 表单填充
api.MultiFillForm(inFilePDF, rd, outDir, fileName, conf)      // 多表单填充
api.MultiFillFormFile(inFilePDF, inFileData, outDir, outFilePDF, merge, conf) // 多表单填充到文件

// 海报生成
api.Poster(rs, outDir, fileName, selectedPages, conf)         // 生成海报
api.PosterFile(inFile, outDir, outFile, selectedPages, cut, conf) // 生成海报到文件

// PDF信息和配置
api.PDFInfo(rs, fileName, selectedPages, fonts, conf)        // 获取PDF信息
api.PDFBookletConfig(val, desc, conf)                       // 小册子配置
api.PDFGridConfig(rows, cols, desc, conf)                   // 网格配置
api.PDFNUpConfig(val, desc, conf)                          // N页合一配置

// 权限和属性
api.Permissions(rs, conf)                                  // 获取权限
api.Properties(rs, conf)                                   // 获取属性

// 页面边界
api.PageBoundaries(s, unit)                               // 设置页面边界
api.PageBoundariesFromBoxList(s)                          // 从盒子列表设置边界

5. 水印操作

go
// 添加文本水印
wm := pdfcpu.TextWatermark{Text: "Confidential", Opacity: 0.5}
api.AddWatermarks("in.pdf", "out.pdf", nil, wm)

// 添加图片水印
wm := pdfcpu.ImageWatermark{FileName: "logo.png", Opacity: 0.3}
api.AddWatermarks("in.pdf", "out.pdf", nil, wm)

// 移除水印
api.RemoveWatermarks("in.pdf", "out.pdf", nil)

6. 附件操作

go
// 添加附件
api.AttachFile("sample.txt", "in.pdf", "out.pdf", nil)

// 提取附件
api.ExtractAttachments("in.pdf", "outDir", nil)

// 列出附件
api.ListAttachments("in.pdf", nil)

// 移除附件
api.RemoveAttachments("in.pdf", "out.pdf", nil)

7. 书签操作

go
// 导出书签
api.ExportBookmarks("in.pdf", "bookmarks.json", nil)

// 导入书签
api.ImportBookmarks("in.pdf", "out.pdf", "bookmarks.json", nil)

// 列出书签
api.ListBookmarks("in.pdf", nil)

8. 图像操作

go
// 导出图像
api.ExtractImages("in.pdf", "outDir", nil)

// 导入图像
api.ImportImages("out.pdf", []string{"image1.jpg"}, nil)

// 导出页面为图像
api.PageToImage("in.pdf", "outDir", nil, 1)

9. 注释操作

go
// 获取注释信息
api.Annotations("in.pdf", selectedPages, conf)

// 添加注释
api.AddAnnotations(rs, w, selectedPages, annotationRenderer, conf)

// 增量添加注释
api.AddAnnotationsAsIncrement(rws, selectedPages, annotationRenderer, conf)

// 添加注释到文件
api.AddAnnotationsFile("in.pdf", "out.pdf", selectedPages, annotationRenderer, conf)

// 批量添加注释
api.AddAnnotationsMap(rs, w, annotMap, conf)

// 增量批量添加注释
api.AddAnnotationsMapAsIncrement(rws, annotMap, conf)

// 批量添加注释到文件
api.AddAnnotationsMapFile("in.pdf", "out.pdf", annotMap, conf)

10. 附件操作

go
// 获取附件信息
api.Attachments(rs, conf)

// 添加附件
api.AddAttachments(rs, w, files, collectFiles, conf)

// 添加附件到文件
api.AddAttachmentsFile("in.pdf", "out.pdf", files, collectFiles, conf)

// 添加关键字
api.AddKeywords(rs, w, files, conf)

// 添加关键字到文件
api.AddKeywordsFile("in.pdf", "out.pdf", files, conf)

11. 书签操作

go
// 获取书签信息
api.Bookmarks(rs, conf)

// 添加书签
api.AddBookmarks(rs, w, bookmarks, replace, conf)

// 添加书签到文件
api.AddBookmarksFile("in.pdf", "out.pdf", bookmarks, replace, conf)

12. 水印操作

go
// 添加水印
api.AddWatermarks(rs, w, selectedPages, watermark, conf)

// 添加水印到文件
api.AddWatermarksFile("in.pdf", "out.pdf", selectedPages, watermark, conf)

// 批量添加水印
api.AddWatermarksMap(rs, w, watermarkMap, conf)

// 批量添加水印到文件
api.AddWatermarksMapFile("in.pdf", "out.pdf", watermarkMap, conf)

// 批量添加多个水印
api.AddWatermarksSliceMap(rs, w, watermarkSliceMap, conf)

// 批量添加多个水印到文件
api.AddWatermarksSliceMapFile("in.pdf", "out.pdf", watermarkSliceMap, conf)

// 添加图片水印
api.AddImageWatermarksFile("in.pdf", "out.pdf", selectedPages, onTop, conf)

// 从Reader添加图片水印
api.AddImageWatermarksForReaderFile("in.pdf", "out.pdf", selectedPages, onTop, reader, conf)

// 添加PDF水印
api.AddPDFWatermarksFile("in.pdf", "out.pdf", selectedPages, onTop, conf)

// 添加文本水印
api.AddTextWatermarksFile("in.pdf", "out.pdf", selectedPages, onTop, text, desc, conf)

13. 页面边界框操作

go
// 创建边界框
api.Box(boxStr, displayUnit)

// 获取页面边界框信息
api.Boxes(rs, selectedPages, conf)

// 添加边界框
api.AddBoxes(rs, w, selectedPages, pageBoundaries, conf)

// 添加边界框到文件
api.AddBoxesFile("in.pdf", "out.pdf", selectedPages, pageBoundaries, conf)

14. 小册子制作

go
// 创建小册子
api.Booklet(rs, w, imgFiles, selectedPages, nup, conf)

// 创建小册子文件
api.BookletFile(inFiles, "out.pdf", selectedPages, nup, conf)

// 从图片创建小册子
api.BookletFromImages(conf, imageFiles, nup)

15. 文档读取和验证

go
// 读取并验证PDF文件
api.ReadAndValidate(rs io.ReadSeeker, conf *model.Configuration) (ctx *model.Context, err error)

// 读取PDF上下文
api.ReadContext(rs io.ReadSeeker, conf *model.Configuration) (*model.Context, error)

// 从文件读取PDF上下文
api.ReadContextFile(inFile string) (*model.Context, error)

// 读取、验证并优化PDF文件
api.ReadValidateAndOptimize(rs io.ReadSeeker, conf *model.Configuration) (ctx *model.Context, err error)

16. 注释和附件操作

go
// 移除注释
api.RemoveAnnotations(rs io.ReadSeeker, w io.Writer, selectedPages, idsAndTypes []string, conf *model.Configuration) error

// 增量移除注释
api.RemoveAnnotationsAsIncrement(rws io.ReadWriteSeeker, selectedPages, idsAndTypes []string, objNrs []int, conf *model.Configuration) error

// 从文件移除注释
api.RemoveAnnotationsFile(inFile, outFile string, selectedPages, idsAndTypes []string, objNrs []int, conf *model.Configuration) error

// 移除附件
api.RemoveAttachments(rs io.ReadSeeker, w io.Writer, files []string, conf *model.Configuration) error

// 从文件移除附件
api.RemoveAttachmentsFile(inFile, outFile string, files []string, conf *model.Configuration) error

17. 书签和表单操作

go
// 移除书签
api.RemoveBookmarks(rs io.ReadSeeker, w io.Writer, conf *model.Configuration) error

// 从文件移除书签
api.RemoveBookmarksFile(inFile, outFile string, conf *model.Configuration) error

// 移除表单字段
api.RemoveFormFields(rs io.ReadSeeker, w io.Writer, fieldIDsOrNames []string, conf *model.Configuration) error

// 从文件移除表单字段
api.RemoveFormFieldsFile(inFile, outFile string, fieldIDsOrNames []string, conf *model.Configuration) error

// 重置表单字段
api.ResetFormFields(rs io.ReadSeeker, w io.Writer, fieldIDsOrNames []string, conf *model.Configuration) error

// 从文件重置表单字段
api.ResetFormFieldsFile(inFile, outFile string, fieldIDsOrNames []string, conf *model.Configuration) error

// 解锁表单字段
api.UnlockFormFields(rs io.ReadSeeker, w io.Writer, fieldIDsOrNames []string, conf *model.Configuration) error

// 从文件解锁表单字段
api.UnlockFormFieldsFile(inFile, outFile string, fieldIDsOrNames []string, conf *model.Configuration) error

18. 页面布局和模式设置

go
// 设置页面布局
api.SetPageLayout(rs io.ReadSeeker, w io.Writer, val model.PageLayout, conf *model.Configuration) error

// 从文件设置页面布局
api.SetPageLayoutFile(inFile, outFile string, val model.PageLayout, conf *model.Configuration) error

// 重置页面布局
api.ResetPageLayout(rs io.ReadSeeker, w io.Writer, conf *model.Configuration) error

// 从文件重置页面布局
api.ResetPageLayoutFile(inFile, outFile string, conf *model.Configuration) error

// 设置页面模式
api.SetPageMode(rs io.ReadSeeker, w io.Writer, val model.PageMode, conf *model.Configuration) error

// 从文件设置页面模式
api.SetPageModeFile(inFile, outFile string, val model.PageMode, conf *model.Configuration) error

// 重置页面模式
api.ResetPageMode(rs io.ReadSeeker, w io.Writer, conf *model.Configuration) error

// 从文件重置页面模式
api.ResetPageModeFile(inFile, outFile string, conf *model.Configuration) error

19. 查看器首选项和权限设置

go
// 设置查看器首选项
api.SetViewerPreferences(rs io.ReadSeeker, w io.Writer, vp model.ViewerPreferences, conf *model.Configuration) error

// 从文件设置查看器首选项
api.SetViewerPreferencesFile(inFile, outFile string, vp model.ViewerPreferences, conf *model.Configuration) error

// 从JSON字节设置查看器首选项
api.SetViewerPreferencesFromJSONBytes(rs io.ReadSeeker, w io.Writer, jsonBytes []byte, conf *model.Configuration) error

// 从JSON文件设置查看器首选项
api.SetViewerPreferencesFileFromJSONFile(inFilePDF, outFilePDF, inFileJSON string, conf *model.Configuration) error

// 重置查看器首选项
api.ResetViewerPreferences(rs io.ReadSeeker, w io.Writer, conf *model.Configuration) error

// 从文件重置查看器首选项
api.ResetViewerPreferencesFile(inFile, outFile string, conf *model.Configuration) error

// 创建文本水印
api.TextWatermark(text, desc string, onTop, update bool, u types.DisplayUnit) (*model.Watermark, error)

// 更新图像水印
api.UpdateImageWatermarksFile(inFile, outFile string, selectedPages []string, onTop bool, conf *model.Configuration) error

// 更新图像
api.UpdateImages(rs io.ReadSeeker, rd io.Reader, w io.Writer, objNr, pageNr int, id string, conf *model.Configuration) error

// 从文件更新图像
api.UpdateImagesFile(inFile, imageFile, outFile string, objNr, pageNr int, id string, conf *model.Configuration) error

// 更新PDF水印
api.UpdatePDFWatermarksFile(inFile, outFile string, selectedPages []string, onTop bool, conf *model.Configuration) error

// 更新文本水印
api.UpdateTextWatermarksFile(inFile, outFile string, selectedPages []string, onTop bool, text, desc string, conf *model.Configuration) error

// 设置权限
api.SetPermissions(rs io.ReadSeeker, w io.Writer, conf *model.Configuration) error

// 验证PDF文件
api.Validate(rs io.ReadSeeker, conf *model.Configuration) error

// 验证PDF上下文
api.ValidateContext(ctx *model.Context) error

// 验证PDF文件
api.ValidateFile(inFile string, conf *model.Configuration) error

// 验证多个PDF文件
api.ValidateFiles(inFiles []string, conf *model.Configuration) error

// 验证签名
api.ValidateSignatures(inFile string, all bool, conf *model.Configuration) ([]*model.SignatureValidationResult, error)

// 验证文件签名
api.ValidateSignaturesFile(inFile string, all, full bool, conf *model.Configuration) ([]string, error)

// 获取查看器首选项
api.ViewerPreferences(rs io.ReadSeeker, conf *model.Configuration) (*model.ViewerPreferences, *model.Version, error)

// 从文件获取查看器首选项
api.ViewerPreferencesFile(inFile string, all bool, conf *model.Configuration) (*model.ViewerPreferences, error)

// 从文件设置权限
api.SetPermissionsFile(inFile, outFile string, conf *model.Configuration) error

20. 文档拆分和页面操作

go
// 按页数拆分文档
api.Split(rs io.ReadSeeker, outDir, fileName string, span int, conf *model.Configuration) error

// 从文件按页数拆分文档
api.SplitFile(inFile, outDir string, span int, conf *model.Configuration) error

// 按页码拆分文档
api.SplitByPageNr(rs io.ReadSeeker, outDir, fileName string, pageNrs []int, conf *model.Configuration) error

// 从文件按页码拆分文档
api.SplitByPageNrFile(inFile, outDir string, pageNrs []int, conf *model.Configuration) error

// 移除页面
api.RemovePages(rs io.ReadSeeker, w io.Writer, selectedPages []string, conf *model.Configuration) error

// 从文件移除页面
api.RemovePagesFile(inFile, outFile string, selectedPages []string, conf *model.Configuration) error

// 旋转页面
api.Rotate(rs io.ReadSeeker, w io.Writer, rotation int, selectedPages []string, conf *model.Configuration) error

// 从文件旋转页面
api.RotateFile(inFile, outFile string, rotation int, selectedPages []string, conf *model.Configuration) error

// 调整页面大小
api.Resize(rs io.ReadSeeker, w io.Writer, selectedPages []string, resize *model.Resize, conf *model.Configuration) error

// 从文件调整页面大小
api.ResizeFile(inFile, outFile string, selectedPages []string, resize *model.Resize, conf *model.Configuration) error

// 裁剪页面
api.Trim(rs io.ReadSeeker, w io.Writer, selectedPages []string, conf *model.Configuration) error

// 从文件裁剪页面
api.TrimFile(inFile, outFile string, selectedPages []string, conf *model.Configuration) error

// 缩放页面
api.Zoom(rs io.ReadSeeker, w io.Writer, selectedPages []string, zoom *model.Zoom, conf *model.Configuration) error

// 从文件缩放页面
api.ZoomFile(inFile, outFile string, selectedPages []string, zoom *model.Zoom, conf *model.Configuration) error

16. 元数据操作

go
// 获取元数据信息
api.Properties("in.pdf", nil)

// 添加/更新元数据
api.AddProperties(rs, w, properties, conf)

// 添加/更新文件元数据
api.AddPropertiesFile("in.pdf", "out.pdf", properties, conf)

配置选项

大多数API函数都接受一个可选的配置参数,你可以通过它来自定义操作行为:

go
// 基本配置
conf := pdfcpu.NewDefaultConfiguration()
conf.ValidationMode = pdfcpu.ValidationRelaxed
conf.OptimizeDuplicateContentStreams = true

// 加密配置
conf.EncryptUsingAES = true
conf.EncryptKeyLength = 256
conf.Permissions = pdfcpu.PermissionsNone

// 水印配置
conf.WatermarkConfig.FontSize = 24
conf.WatermarkConfig.Color = "rgb(1.0, 0, 0)"

错误处理

所有API函数都会返回一个error类型,建议在生产环境中妥善处理这些错误:

go
if err := api.Validate("in.pdf", nil); err != nil {
    log.Fatalf("验证失败: %v", err)
}

性能优化建议

  1. 处理大文件时的内存优化:

    go
    conf := pdfcpu.NewDefaultConfiguration()
    conf.StatsFileName = "stats.csv" // 启用性能统计
    conf.ReadBufferSize = 1024 * 1024 // 设置读取缓冲区大小
  2. 并发处理多个文件:

    go
    var wg sync.WaitGroup
    for _, file := range files {
        wg.Add(1)
        go func(f string) {
            defer wg.Done()
            api.Optimize(f, f+".opt.pdf", nil)
        }(file)
    }
    wg.Wait()

注意事项

  1. 在处理大文件时,建议适当调整内存配置
  2. 某些操作可能需要读写权限,请确保应用有足够的文件系统权限
  3. 建议在进行文件修改操作前先进行备份
  4. 密码保护的PDF文件需要提供正确的密码才能操作
  5. 水印和注释操作可能会增加文件大小,建议在操作后进行优化
  6. 并发处理时注意资源限制和错误处理

更多资源

由VitePress强力驱动