pdfcpu 命令 · 参数 · 示例完全手册
适用版本:pdfcpu v0.11+ / v0.12(Apache-2.0) 官方站点:https://pdfcpu.io · 源码:https://github.com/pdfcpu/pdfcpu 所有命令均可追加 --help 查看权威用法:pdfcpu [command] --help 本文示例同时给出 CLI 原生命名 与配套 C# 封装(PdfCpu 类) 的调用写法。
目录
快速上手
全局通用规则
2.1 通用 flag
2.2 页面选择语法 --pages
2.3 显示单位 --unit
2.4 description 配置字符串通识
2.5 颜色与定位锚点
核心命令
生成与排版命令
印章与水印
内容提取
页面增删
附件、Portfolio 与注释
书签、页面框与文档元数据
加密、权限与签名
表单与字体
附录 A:C# 封装方法速查表
附录 B:常见坑与最佳实践
1. 快速上手 1 2 3 4 5 6 7 8 9 brew install pdfcpu scoop install pdfcpu go install github.com/pdfcpu/pdfcpu/cmd/pdfcpu@latest pdfcpu validate in.pdf pdfcpu merge out.pdf a.pdf b.pdf pdfcpu split in.pdf ./out 1
版本与自检
命令
作用
pdfcpu version
打印版本
pdfcpu info in.pdf...
打印文件信息(页数、页面尺寸、加密状态、权限、书签等)
pdfcpu paper
打印全部支持的纸张尺寸
pdfcpu selectedpages
打印 --pages 的完整语法
pdfcpu config list / config reset
查看 / 重置配置文件
排障第一步 :任何异常都先跑 pdfcpu validate -vv <file.pdf>,官方 issue 模板要求附带它的输出。
2. 全局通用规则 2.1 通用 flag 绝大多数命令都支持(下表中 -x / --xxx 两种写法等价,pdfcpu 支持单字母 Unix 风格缩写):
flag
说明
取值
-v / --verbose
打开日志
—
-vv
详细日志(报 bug 时请附它的输出 )
—
-q / --quiet
关闭 stdout 输出
—
--force
覆盖已存在输出文件 / 写入非空目录
—
-o / --offline
禁止出站 HTTP(校验链接、填充图片框时用)
—
-c / --conf
指定配置目录
$path 或 disable
-u / --unit
输入显示单位
po(ints)、in(ches)、cm、mm
-p / --pages
页面选择,见 2.2
表达式串
-m / --mode
命令相关模式(validate / extract / encrypt / split / stamp / watermark 等)
见各命令
--upw
用户口令(打开文档的口令)
—
--opw
拥有者口令(改权限 / 口令的口令)
—
⚠️ 口令会被写进命令行 :同机其他用户 ps 即可看到 --upw/--opw。敏感场景请改用 pdfcpu 的 Go API,或至少保证执行环境隔离。
C# 侧对应 :PdfCpuOptions 已强类型封装 Pages、UserPassword、OwnerPassword、Verbosity、Quiet;-u、-c、--force、--json 等通过 ExtraFlags 兜底传入。
1 2 3 4 5 6 var opt = new PdfCpuOptions { Pages = "1-3,7-" , OwnerPassword = "opw" , Verbosity = PdfCpuVerbosity.VeryVerbose, ExtraFlags = "-u cm --force" };
2.2 页面选择语法 --pages 值是逗号分隔的表达式列表:
表达式
含义
even / odd
偶数页 / 奇数页
#
指定页,如 5
#-#
页范围,如 1-10
!# / n#
排除某页,如 !6
!#-#
排除范围
#-
从第 # 页到最后一页
-#
从第一页到第 # 页
!#-
排除第 # 页到末尾
!-#
排除第一页到第 # 页
l
最后一页
nl
排除最后一页
#-l-1
第 # 页到「倒数第二页」
1 2 3 4 --pages -3,5,7- --pages '4-7,!6' -p odd,n1,nl -p even,l
哪些命令支持 --pages :trim(必需)、collect(必需)、rotate、crop、resize、zoom、cut、ndown、poster、stamp、watermark、extract、pages insert、pages remove、annotations、images list、info 等。
2.3 显示单位 --unit -u po|in|cm|mm,影响 description 中「用户单位」数值的解释(如 dim:15 10 在 -u cm 下即 15cm × 10cm)。默认是 points(1pt = 1/72 英寸,A4 = 595 × 842)。
2.4 description 配置字符串通识 一批命令(import / nup / grid / booklet / ndown / cut / poster / crop / resize / zoom / stamp / watermark / boxes add / pages insert)用逗号分隔的 key:value 串 描述布局,例如:
1 "form:A4L, dim:595 842, pos:c, off:0 0, sc:0.5 rel, bo:on, ma:3"
规则:
只需写与默认值不同的项 ;
参数名支持前缀补全 ,例如 f:=form:=formsize:、dim:=dimensions:、pos:=position:、sc:=scale:=scalefactor:、bo:=border:、ma:=margins:、bgcol:=backgroundcolor:、c:=color:=fillcolor:、mo:=rendermode:、d:=diagonal:、op:=opacity:、o:(在 nup/grid 中)=orientation:;
⚠️ 前缀补全有歧义会报错 (历史 issue #851:d: 在 import 中同时匹配 dim/dpi)。报错 ambiguous parameter prefix 时改用完整名;
互斥项 :dimensions 与 formsize 只能二选一;rotation 与 diagonal 只能二选一;
值为空串 "" 表示全部使用默认值。
2.5 颜色与定位锚点 颜色 三种写法:
写法
示例
三个 0.0~1.0 强度值
c:.6 .2 .9 / fillc:0.5 0.5 0.5(灰)
十六进制
fillc:#3277d3、bgcol:#beded9
颜色名
bgcol:DarkGray
定位锚点 (用于 pos: / position:):
左
中
右
上
tl
tc
tr
中
l
c
r
下
bl
bc
br
import 额外支持 pos:full(图片铺满整页,默认)。
3. 核心命令 3.1 validate — 校验 1 pdfcpu validate inFile... [flags]
flag
说明
取值
默认
-m / --mode
校验模式
strict、relaxed
strict
--upw / --opw
口令
—
—
strict:严格按 PDF 32000-1:2008(PDF 1.7)校验;
relaxed:忽略现实中常见的规范违规。
1 2 3 pdfcpu validate in.pdf pdfcpu validate -mode relaxed in.pdf pdfcpu validate *.pdf
1 2 3 await pdf.ValidateAsync("in.pdf" ); await pdf.ValidateAsync("in.pdf" , PdfCpuValidationMode.Relaxed);await pdf.ValidateAsync(new [] { "a.pdf" , "b.pdf" });
3.2 optimize — 优化体积 1 pdfcpu optimize inFile [outFile] [flags]
去除重复字体、图片等冗余资源并最大化压缩。
flag
说明
--stats csvFile
把内存占用、PDF 对象使用等统计追加写入 CSV(便于批量对比)
--rmenc
同时移除加密
--rmsig
同时移除签名
1 2 pdfcpu optimize in.pdf out.pdf pdfcpu optimize --stats stats.csv in.pdf
1 2 await pdf.OptimizeAsync("in.pdf" , "out.pdf" , new PdfCpuOptimizeOptions { StatsCsvFile = "stats.csv" , RemoveSignatures = true });
官方明确提醒:merge / stamp / watermark / trim / rotate 产出的已是处理后的 PDF,不要 在其后再叠一次 optimize。
3.3 merge — 合并 1 pdfcpu merge outFile inFile... [flags]
flag
说明
取值
默认
-m / --mode
合并模式
create、append、zip
create
--sort
按文件名排序输入
—
off
-b / --bookmarks
为每个输入文件生成书签
—
off
-d / --divider
在文件边界插入分隔页
—
off
1 2 3 pdfcpu merge book.pdf chapter*.pdf pdfcpu merge -mode append book.pdf new.pdf pdfcpu merge -bookmarks full.pdf c1.pdf c2.pdf
1 2 3 await pdf.MergeAsync("book.pdf" , new [] { "c1.pdf" , "c2.pdf" });await pdf.MergeAsync("book.pdf" , files, new PdfCpuMergeOptions { Mode = PdfCpuMergeMode.Create, Bookmarks = true , Sort = true });
3.4 split — 拆分 1 pdfcpu split inFile outDir [ span | pageNr... ] [flags]
flag
说明
取值
默认
-m / --mode
拆分模式
span、bookmark、page
span
1 2 3 4 pdfcpu split in.pdf ./out 1 pdfcpu split in.pdf ./out 3 pdfcpu split -m bookmark in.pdf ./out pdfcpu split -m page in.pdf ./out 2 4 10
1 2 3 await pdf.SplitAsync("in.pdf" , "./out" ); await pdf.SplitAsync("in.pdf" , "./out" , PdfCpuSplitMode.Span, new [] { "3" });await pdf.SplitAsync("in.pdf" , "./out" , PdfCpuSplitMode.Page, new [] { "2" , "4" , "10" });
3.5 trim — 按页裁剪出新文档 1 pdfcpu trim inFile [outFile] [flags] # --pages 必需
按页面选择 生成新 PDF(不是 裁剪页面内容,也不是去白边 —— 那是 crop)。
1 2 3 pdfcpu trim --pages even test.pdf trimmed.pdf pdfcpu trim -p 1 test.pdf first.pdf pdfcpu trim book.pdf essence.pdf --pages '!2-4,!12-'
trim 不会保留:Annotations、Outlines、Struct Trees、Forms。
1 await pdf.TrimAsync("test.pdf" , "even" , "trimmed.pdf" );
3.6 rotate — 旋转 1 pdfcpu rotate inFile rotation [outFile] [flags]
rotation 必须是 90 的整数倍 (顺时针为正);
配合 --pages 只旋转部分页。
1 2 pdfcpu rotate in.pdf 90 pdfcpu rotate -pages 2,5 in.pdf -90 out.pdf
1 await pdf.RotateAsync("in.pdf" , 90 , "out.pdf" , new PdfCpuOptions { Pages = "2,5" });
3.7 collect — 按序重组页面 1 pdfcpu collect inFile [outFile] [flags] # --pages 必需
按页面选择生成一个自定义顺序的 PDF,可重复引用同一页。
1 2 pdfcpu collect -pages 1,1,1,2-l-1 in.pdf out.pdf pdfcpu collect -p '2-,!5,!l-4,!l' in.pdf out.pdf
1 await pdf.CollectAsync("in.pdf" , "out.pdf" , new PdfCpuOptions { Pages = "1,1,1,2-l-1" });
3.8 crop — 设置裁剪框 1 pdfcpu crop description inFile [outFile] [flags]
description 描述 cropbox 区域,三种写法(详见 Box 语法 ):
写法
示例
含义
绝对矩形
[0 0 200 200] 或 xmin:0 ymin:10 xmax:200 ymax:150
用户空间坐标
相对父框的四边内缩
100(四边各 100)、15 10 15(上/左右/下)、5%(相对 5%)、-10(负值→扩展 mediabox)
绝对值或 abs / rel
锚点 + 尺寸
pos:bl, off:1 1, dim:25% 25%
锚定左下角、偏移 1/1、尺寸为父框 25%
1 2 3 pdfcpu crop -- "[0 0 200 200]" in.pdf out.pdf pdfcpu crop -u cm -- "100" in.pdf out.pdf pdfcpu crop -u mm -- "15 10 15" in.pdf out.pdf
1 2 3 await pdf.CropAsync("[0 0 200 200]" , "in.pdf" , "out.pdf" );await pdf.CropAsync("15 10 15" , "in.pdf" , "out.pdf" , new PdfCpuOptions { ExtraFlags = "-u mm" });
3.9 resize — 缩放页面 1 pdfcpu resize description inFile [outFile] [flags]
参数
说明
scalefactor / scale / sc
缩放因子,>1 放大
dimensions / dim
自定义尺寸,(宽 高),某一维给 0 表示按比例
formsize / papersize / form / f
纸张尺寸,可加 L / P 强制横/纵向
enforce
仅在设置了 dimensions 时生效,强制方向
bgcolor / bgcol
未使用区域的背景色
border
绘制内容区边框
1 2 3 4 pdfcpu resize "scale:2" in.pdf out.pdf pdfcpu resize -pages 1-3 -- "sc:.5" in.pdf out.pdf pdfcpu resize -u cm -- "dim:40 0" in.pdf out.pdf pdfcpu resize "f:A4P, bgcol:#d0d0d0" in.pdf out.pdf
1 2 await pdf.ResizeAsync("scale:2" , "in.pdf" , "out.pdf" );await pdf.ResizeAsync("form:A4" , "in.pdf" , "out.pdf" );
3.10 zoom — 缩放显示比例 1 pdfcpu zoom description inFile [outFile] [flags]
参数同 resize 族(scalefactor / dimensions / formsize / bgcolor / border),用于调整页面内容的显示缩放。
1 await pdf.ZoomAsync("scale:0.5, form:A4" , "in.pdf" , "out.pdf" );
3.11 info — 文件信息 1 pdfcpu info inFile... [flags]
flag
说明
-p / --pages
输出所选页的页面边界(含 w 宽、h 高、ar 宽高比)
--fonts
包含字体信息
-j / --json
输出 JSON
1 2 3 pdfcpu info test.pdf pdfcpu info test.pdf -u cm --pages 1,2 pdfcpu info test.pdf --json
1 2 await pdf.InfoAsync("test.pdf" , new PdfCpuOptions { Pages = "1,2" , ExtraFlags = "-u cm" });
3.12 其他
命令
C#
pdfcpu version
pdf.VersionAsync()
pdfcpu paper
pdf.PaperAsync()
pdfcpu selectedpages
pdf.SelectedPagesAsync()
pdfcpu config list / config reset
pdf.ConfigListAsync() / pdf.ConfigResetAsync()
4. 生成与排版命令 4.1 import — 图片转 PDF 1 pdfcpu import [description] outFile imageFile... [flags]
支持 JPG / PNG / WEBP / TIFF;每张图一页;outFile 已存在则追加 (适合封面 + 相册)。
参数
说明
默认
dimensions / dim
页面尺寸(宽 高)
595 842
dpi
目标分辨率
72
formsize / papersize / form / f / p
纸张尺寸,加 L/P 强制方向
A4
position / pos
full 或锚点
full
offset / off
偏移 (dx dy)
0 0
scalefactor / scale / sc
缩放,可加 abs / rel
0.5 rel
gray
转灰度
off
sepia
复古色
off
backgroundcolor / bgcol
背景色
none
默认串:'f:A4, dim:595 842, dpi:72, pos:full, off:0 0, scale:0.5 rel, gray:off, sepia:off'
1 2 3 4 pdfcpu import photo.pdf photo.png pdfcpu import -- 'f:A5, pos:c' photo.pdf photo.jpg pdfcpu import -- 'form:A5L, pos:bl' photo.pdf photo.jpg pdfcpu import -- "dim:595 842, f:A4, pos:full, dpi:300" album.pdf *.jpg
1 2 await pdf.ImportAsync("photo.pdf" , new [] { "photo.png" });await pdf.ImportAsync("album.pdf" , jpgs, "form:A4, pos:c, dpi:300" );
4.2 nup — N 合一排版(减少页数) 1 pdfcpu nup [description] outFile n inFile | imageFiles... [flags]
参数
说明
默认
dimensions / dim
单元格尺寸
595 842
formsize / papersize / form
纸张尺寸(L/P)
A4
orientation / o
rd(右下)、dr、ld、dl,仅对 PDF 输入
rd
enforce
强制方向
on
border / bo
单元格边框
on
margin / ma
边距 >= 0
0
backgroundcolor / bgcol
背景色
none
1 2 pdfcpu nup out.pdf 4 in.pdf pdfcpu nup -- 'form:A4, bo:off, ma:0' out.pdf 2 in.pdf
1 await pdf.NUpAsync("out.pdf" , 4 , new [] { "in.pdf" }, "form:A4, border:off, margin:0" );
4.3 grid — 网格排版(便于浏览) 1 pdfcpu grid [description] outFile m n inFile | imageFiles... [flags]
参数同 nup(m = 行、n = 列)。
1 pdfcpu grid -- 'form:A4, d:500 500, o:rd, bo:off, ma:20' out.pdf 3 4 in.pdf
1 await pdf.GridAsync("out.pdf" , 3 , 4 , new [] { "in.pdf" }, "form:A4, margin:20" );
4.4 ndown — 把一页切成 n 页(nup 的逆运算) 1 pdfcpu ndown [description] n inFile outDir [outFile] [flags]
n 合法值:2、3、4、6、8、9、12、16 (2=1x2、4=2x2、8=2x4、9=3x3、12=3x4、16=4x4);
description 仅支持 margin(粘合区)、bgcolor(粘合区颜色)、border(内容区边框)。
1 2 3 pdfcpu ndown 2 test.pdf . pdfcpu ndown 4 test.pdf . pdfcpu ndown -u cm -- "margin:1, bgcol:DarkGray, border:on" 4 test.pdf .
1 2 3 await pdf.NDownAsync(4 , "test.pdf" , "./out" , description: "margin:1, bgcol:DarkGray, border:on" , options: new PdfCpuOptions { ExtraFlags = "-u cm" });
4.5 poster — 生成海报 1 pdfcpu poster description inFile outDir [outFile] [flags]
参数
说明
scalefactor / scale
先放大(>1.0),如 scale:2.0
formsize / papersize / form
用哪种纸拼(加 L/P)
dimensions / dim
自定义瓦片尺寸
margin
粘合区宽度
bgcolor
粘合区颜色
border
绘制内容区边框
1 2 3 pdfcpu poster "f:A4" test.pdf . pdfcpu poster "f:A4, scale:2.0" test.pdf . pdfcpu poster -u cm -- "dim:15 10, margin:1, border:on" test.pdf .
1 2 3 await pdf.PosterAsync("form:A4" , "test.pdf" , "./out" );await pdf.PosterAsync("dim:15 10, margin:1, border:on" , "test.pdf" , "./out" , options: new PdfCpuOptions { ExtraFlags = "-u cm" });
4.6 cut — 自定义切页(底层命令) 1 pdfcpu cut description inFile outDir [outFile] [flags]
参数
说明
horizontal / hor
在高度比例处横切(原点左上),如 .25 或 .33 .66
vertical / vert
在宽度比例处纵切
margin
粘合区
bgcolor
粘合区颜色
border
内容区边框
1 2 3 4 pdfcpu cut -- "hor:.25" test.pdf . pdfcpu cut -- "hor:.25, vert:.75" test.pdf . pdfcpu cut -- "hor:.33 .66" in.pdf outDir pdfcpu cut -- "hor:.5, ver:.5" in.pdf outDir
1 await pdf.CutAsync("hor:.25, vert:.75" , "test.pdf" , "./out" );
4.7 booklet — 制作小册子 / zine 1 pdfcpu booklet [description] outFile n inFile | imageFiles... [flags]
n = 每张纸单面能放的页数:2 (1x2 长边)、4 (2x2)、6 (2x3 长边)、8 (2x4 长边 / 4x2 短边);
description 参数:
参数
说明
默认
dimensions / dim
页面尺寸
595 842
formsize / papersize / p
纸张尺寸
A4
btype
装订排版方式:booklet、bookletadvanced、perfectbound
booklet
binding
装订边:long / short
long
multifolio
多帖装订,仅 PDF 输入
off
foliosize
每帖页数,仅 multifolio 用
8
guides / g
显示辅助线
off
border / bo
边框
off
margin / ma
边距
0
backgroundcolor / bgcol
背景色
none
1 2 3 pdfcpu booklet 'p:A4, border:on' booklet.pdf 2 pageSequence.pdf pdfcpu booklet 'p:A4, bo:off, g:on, ma:10, bgcol:#beded9' zine.pdf 4 seq.pdf pdfcpu booklet 'p:A4, multifolio:on, foliosize:8' hardback.pdf 2 in.pdf
1 2 await pdf.BookletAsync("zine.pdf" , 4 , new [] { "seq.pdf" }, "form:A4, border:off, guides:on, margin:10" );
4.8 create — 用 JSON 生成 PDF 内容 1 pdfcpu create inFileJSON [inFile] outFile [flags]
有 inFile 时把新内容追加到既有页面内容之上;无则覆盖 outFile。
最小可用 JSON:
1 2 3 4 5 6 7 8 9 10 11 12 { "pages" : { "1" : { "content" : { "text" : [ { "value" : "Hello pdfcpu user!" , "anchor" : "center" , "font" : { "name" : "Helvetica" , "size" : 12 } } ] } } } }
1 2 pdfcpu create content.json out.pdf pdfcpu create content.json template.pdf out.pdf
1 2 await pdf.CreateAsync("content.json" , "out.pdf" );await pdf.CreateAsync("content.json" , "out.pdf" , "template.pdf" );
完整 JSON 语法参考源码目录 pkg/samples/create/*。
5. 印章与水印(stamp / watermark) 语义区别(重要) :
位置
适用
stamp
压在页面内容之上
签名、盖章、编号
watermark
沉在页面内容之下 (背景)
「机密」「草稿」底纹
⚠️ 扫描件 PDF 通常是整页位图,会完全遮住背景层的水印 。此时改用 stamp 并把 opacity 调到 < 1 来模拟水印效果。
1 2 3 pdfcpu stamp add|update [description] inFile [outFile] -m text|image|pdf -- string|file pdfcpu watermark add|update [description] inFile [outFile] -m text|image|pdf -- string|file pdfcpu stamp|watermark remove inFile [outFile]
-m / --mode 三种模式:
模式
内容
备注
text
字符串
支持 %p(当前页号)、%P(总页数)、\n 换行
image
图片文件
.jpg/.jpeg/.png/.tif/.tiff/.webp
pdf
PDF 文件
file.pdf:3 用第 3 页;省略页码则为多页依次盖章 (multi stamping)
5.1 description 全参数 通用参数
参数
说明
默认
position / pos
锚点 tl tc tr l c r bl bc br(自由定位用 pos:bl)
c
offset / off
偏移 (dx dy) 用户单位
0 0
scalefactor / scale / sc
0.0 < s <= 1.0,后跟 abs 或 rel
0.5 rel
rotation / rot
旋转角 -180 ~ 180
0
diagonal / d
1=左下→右上,2=左上→右下(与 rotation 互斥 )
1
opacity / op
不透明度 0.0~1.0
1
margins / ma
边距:i / i j / i j k / i j k l
0
border / bo
边框:i {color} {round},需先设 bgcolor
0
bgcolor / bgcol
背景色(设定后才有包围盒)
none
url
仅 stamp :加链接注释(省略 https://)
—
仅 text 模式
参数
说明
默认
fontname / font / f
字体名,见 pdfcpu fonts list
Helvetica
scriptname
CJK 脚本名,用于避免嵌入字体
—
points / p
字号(仅配合 abs 绝对缩放时生效 )
24
aligntext / align
文本水平对齐 l/r/c/j
c
fillcolor / color / fillc / c
填充色
#808080
strokecolor / strokec
描边色
#808080
rendermode / mo / m
0 填充、1 描边、2 填充+描边
0
rtl
右到左渲染(用户字体)
off
默认串:
1 2 'f:Helvetica, points:24, rtl:off, scale:0.5 rel, pos:c, off:0 0, align:c, fillc:#808080, strokec:#808080, rot:0, d:1, op:1, mo:0, ma:0, bo:0'
5.2 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 pdfcpu watermark add -m text -- 'This is a watermark' '' in.pdf out.pdf pdfcpu watermark add -m text -- 'Draft' 'scale:.9, d:2, c:.6 .2 .9' in.pdf out.pdf pdfcpu watermark add -m text -- 'Draft' 'scale:.9, rot:0, mo:1' in.pdf out.pdf pdfcpu stamp add -m text -- 'Draft' 'scale:1, rot:45, mo:2, c:.2 .7 .9' in.pdf out.pdf pdfcpu stamp add -m text -- 'Some multi\nline text' \ 'margins:5, bo:7 round .3 .7 .7, fillc:#3277d3, bgcol:#beded9, rot:0' in.pdf out.pdf pdfcpu stamp add -m text -- "Page %p of %P" "sc:1.0 abs, pos:bc, rot:0" in.pdf out.pdf pdfcpu stamp add -m image -- 'sign.png' 'pos:bl, rot:0, off:100 80, scalef:0.3 abs' in.pdf out.pdf pdfcpu stamp add -m pdf -- 'stamp.pdf:3' '' in.pdf out.pdf pdfcpu stamp add -m pdf -- 'stamp.pdf' '' in.pdf out.pdf pdfcpu watermark add -m text -pages 1-3 -- '机密' 'rot:0, op:0.3' in.pdf out.pdf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 await pdf.WatermarkAddAsync("机密" , PdfCpuStampMode.Text, "scale:1, rot:45, op:0.3" , "in.pdf" , "out.pdf" , new PdfCpuOptions { Pages = "1-3" }); await pdf.StampAddAsync("sign.png" , PdfCpuStampMode.Image, "pos:bl, rot:0, off:100 80, scalef:0.3 abs" , "in.pdf" , "out.pdf" ); await pdf.StampAddAsync("stamp.pdf" , PdfCpuStampMode.Pdf, "" , "in.pdf" , "out.pdf" );await pdf.StampRemoveAsync("in.pdf" , "out.pdf" );await pdf.WatermarkRemoveAsync("in.pdf" , "out.pdf" , new PdfCpuOptions { Pages = "1-3" });
1 pdfcpu extract inFile outDir [flags]
flag
说明
取值
-m / --mode
提取类型
image、font、content、page、meta
-p / --pages
页面选择(mode=page 时有效)
表达式
1 2 3 4 5 pdfcpu extract -mode image in.pdf ./imgs pdfcpu extract -mode font in.pdf ./fonts pdfcpu extract -mode content in.pdf ./src pdfcpu extract -mode page -pages 1-5 in.pdf ./pages pdfcpu extract -mode meta in.pdf ./meta
1 2 3 await pdf.ExtractAsync("in.pdf" , "./imgs" , PdfCpuExtractMode.Image);await pdf.ExtractAsync("in.pdf" , "./pages" , PdfCpuExtractMode.Page, new PdfCpuOptions { Pages = "1-5" });
6.2 images — 图片管理 1 2 3 pdfcpu images list inFile... [flags] pdfcpu images extract inFile outDir [flags] pdfcpu images update inFile imageFile [outFile] [ objNr | (pageNr Id) ] [flags]
1 2 3 4 pdfcpu images list -p "1-5" gallery.pdf pdfcpu images extract in.pdf ./imgs pdfcpu images update in.pdf new.png out.pdf 42 pdfcpu images update in.pdf new.png out.pdf 3 1
1 2 3 4 await pdf.ImagesListAsync(new [] { "gallery.pdf" }, new PdfCpuOptions { Pages = "1-5" });await pdf.ImagesExtractAsync("in.pdf" , "./imgs" );await pdf.ImagesUpdateAsync("in.pdf" , "new.png" , objectNumber: 42 , "out.pdf" );await pdf.ImagesUpdateAsync("in.pdf" , "new.png" , pageNumber: 3 , id: 1 , "out.pdf" );
7. 页面增删(pages) 7.1 pages insert — 插入空白页 1 pdfcpu pages insert [description] inFile [outFile] [flags]
flag
说明
取值
默认
-p / --pages
在哪些页前/后插入;不指定则每一页 都插
表达式
全部
-m / --mode
插在所选页之前还是之后
before、after
before
description 可选,用于指定新页尺寸(如 dim:4.85in 7.84in / form:A4),视 pdfcpu 版本支持情况而定 ,旧版本可能忽略。
1 2 3 pdfcpu pages insert in.pdf pdfcpu pages insert in.pdf out.pdf --pages 1-5 pdfcpu pages insert in.pdf out.pdf --pages l --mode after
1 2 3 4 5 await pdf.PagesInsertAsync("in.pdf" , "out.pdf" , options: new PdfCpuOptions { Pages = "1-5" }); await pdf.PagesInsertAsync("in.pdf" , "out.pdf" , options: new PdfCpuOptions { Pages = "l" , ExtraFlags = "--mode after" });
7.2 pages remove — 删除页 1 pdfcpu pages remove inFile [outFile] [flags] # --pages 必需
1 2 pdfcpu pages remove -pages 3-6 in.pdf out.pdf pdfcpu pages remove -p '1-,!5' in.pdf out.pdf
1 await pdf.PagesRemoveAsync("in.pdf" , "3-6" , "out.pdf" );
8. 附件、Portfolio 与注释 8.1 attachments — 内嵌附件 1 2 3 4 pdfcpu attachments list inFile pdfcpu attachments add inFile file... pdfcpu attachments remove inFile [file...] pdfcpu attachments extract inFile outDir [file...]
remove / extract 省略文件名 = 全部。
1 2 3 4 pdfcpu attachments list in.pdf pdfcpu attachments add in.pdf a.xlsx b.docx pdfcpu attachments remove in.pdf a.xlsx pdfcpu attachments extract in.pdf ./att
1 2 3 4 await pdf.AttachmentsListAsync("in.pdf" );await pdf.AttachmentsAddAsync("in.pdf" , new [] { "a.xlsx" , "b.docx" });await pdf.AttachmentsRemoveAsync("in.pdf" , new [] { "a.xlsx" });await pdf.AttachmentsExtractAsync("in.pdf" , "./att" );
8.2 portfolio — Portfolio(PDF 包) 语法与 attachments 完全对称:list / add / remove / extract。
1 2 3 4 await pdf.PortfolioListAsync("in.pdf" );await pdf.PortfolioAddAsync("in.pdf" , files);await pdf.PortfolioRemoveAsync("in.pdf" );await pdf.PortfolioExtractAsync("in.pdf" , "./out" );
8.3 annotations — 注释 1 2 pdfcpu annotations list inFile pdfcpu annotations remove inFile [outFile] [ objNr | annotId | annotType ]...
1 2 3 4 pdfcpu annotations list in.pdf pdfcpu annotations remove in.pdf pdfcpu annotations remove in.pdf out.pdf 42 pdfcpu annotations remove in.pdf out.pdf Text
1 2 3 await pdf.AnnotationsListAsync("in.pdf" );await pdf.AnnotationsRemoveAsync("in.pdf" , "out.pdf" , new [] { "42" });await pdf.AnnotationsRemoveAsync("in.pdf" , "out.pdf" , new [] { "Text" });
9. 书签、页面框与文档元数据 9.1 bookmarks — 书签 / 大纲 1 2 3 4 pdfcpu bookmarks list inFile pdfcpu bookmarks import inFile inFileJSON [outFile] # -r / --replace 覆盖已有书签 pdfcpu bookmarks export inFile [outFileJSON] pdfcpu bookmarks remove inFile [outFile]
导出 JSON 结构(真实样例):
1 2 3 4 5 6 7 8 { "header" : { "source" : "A Sample Document" , "version" : "pdfcpu v0.11.0 dev" } , "bookmarks" : [ { "title" : "Section 1" , "page" : 1 } , { "title" : "Section 2" , "page" : 2 , "kids" : [ { "title" : "Section 2.1" , "page" : 2 } ] } ] }
已知限制:该格式不保存页内精确位置 (指向页中某一行的书签会被归一到页首)。
1 2 3 4 pdfcpu bookmarks list in.pdf pdfcpu bookmarks export in.pdf bm.json pdfcpu bookmarks import -r in.pdf bm.json out.pdf pdfcpu bookmarks remove in.pdf out.pdf
1 2 3 4 5 await pdf.BookmarksListAsync("in.pdf" );await pdf.BookmarksExportAsync("in.pdf" , "bm.json" );await pdf.BookmarksImportAsync("in.pdf" , "bm.json" , "out.pdf" , new PdfCpuOptions { ExtraFlags = "-r" }); await pdf.BookmarksRemoveAsync("in.pdf" , "out.pdf" );
9.2 boxes — 页面边界框 1 2 3 pdfcpu boxes list [boxTypes] inFile pdfcpu boxes add description inFile [outFile] pdfcpu boxes remove boxTypes inFile [outFile]
五种框:media、crop、bleed、trim、art。
media 必填,是 crop 的默认与父框;
crop 是 art / bleed / trim 的默认与父框。
description 语法同 crop ,并支持一次指定多个框:
1 2 3 pdfcpu boxes list -- "bleed,trim" in.pdf pdfcpu boxes add -- "crop:[10 10 200 200], trim:5, bleed:trim" in.pdf pdfcpu boxes remove -- "t,b" in.pdf
1 2 3 await pdf.BoxesListAsync("in.pdf" , "bleed,trim" );await pdf.BoxesAddAsync("crop:[10 10 200 200], trim:5" , "in.pdf" , "out.pdf" );await pdf.BoxesRemoveAsync("trim,bleed" , "in.pdf" , "out.pdf" );
9.3 keywords — 文档关键字 1 2 3 pdfcpu keywords list inFile pdfcpu keywords add inFile keyword... pdfcpu keywords remove inFile [keyword...]
1 2 pdfcpu keywords add in.pdf 合同 2026 pdfcpu keywords list in.pdf
1 2 3 await pdf.KeywordsAddAsync("in.pdf" , new [] { "合同" , "2026" });await pdf.KeywordsListAsync("in.pdf" );await pdf.KeywordsRemoveAsync("in.pdf" );
9.4 properties — 文档属性 1 2 3 pdfcpu properties list inFile pdfcpu properties add inFile nameValuePair... pdfcpu properties remove inFile [name...]
1 2 pdfcpu properties add in.pdf title=年度报告 author=张三 pdfcpu properties list in.pdf
1 2 await pdf.PropertiesAddAsync("in.pdf" , new [] { "title=年度报告" , "author=张三" });await pdf.PropertiesListAsync("in.pdf" );
9.5 pagelayout / pagemode — 打开时的显示方式 1 2 pdfcpu pagelayout list|set|reset inFile [value] pdfcpu pagemode list|set|reset inFile [value]
pagelayout 取值:SinglePage、OneColumn、TwoColumnLeft、TwoColumnRight、TwoPageLeft、TwoPageRight
pagemode 取值:UseNone、UseOutlines、UseThumbs、FullScreen、UseOC、UseAttachments
1 2 3 pdfcpu pagelayout set in.pdf TwoPageLeft pdfcpu pagemode set in.pdf UseOutlines pdfcpu pagelayout reset in.pdf
1 2 3 await pdf.PageLayoutSetAsync("in.pdf" , PdfCpuPageLayout.TwoPageLeft);await pdf.PageModeSetAsync("in.pdf" , PdfCpuPageMode.UseOutlines);await pdf.PageLayoutResetAsync("in.pdf" );
9.6 viewerpref — 阅读器偏好 1 2 3 pdfcpu viewerpref list [-a] [-j] inFile pdfcpu viewerpref set inFile ( inFileJSON | JSONstring ) pdfcpu viewerpref reset inFile
list 的 -a / --all 输出含默认值,-j / --json 输出 JSON;
set 接受 JSON 文件路径或 JSON 字符串。
受控项包括 HideToolbar、HideMenubar、FitWindow、CenterWindow、DisplayDocTitle、NonFullScreenPageMode 等。
1 2 3 4 pdfcpu viewerpref list test.pdf pdfcpu viewerpref list -all test.pdf pdfcpu viewerpref set test.pdf '{"DisplayDocTitle": true}' pdfcpu viewerpref reset test.pdf
1 2 3 4 await pdf.ViewerPreferencesListAsync("test.pdf" , new PdfCpuOptions { ExtraFlags = "-a" }); await pdf.ViewerPreferencesSetAsync("test.pdf" , "{\"DisplayDocTitle\": true}" );await pdf.ViewerPreferencesResetAsync("test.pdf" );
10. 加密、权限与签名 10.1 encrypt — 加密 1 pdfcpu encrypt inFile [outFile] [flags]
flag
说明
取值
默认
-m / --mode
算法
rc4、aes
aes
--key
密钥长度
rc4: 40/128;aes: 40/128/256
256
--perm
打开后的权限
none、all
none
--upw
用户口令(打开文档用)
—
可选
--opw
拥有者口令(改权限用),pdfcpu 要求非空
—
必填
两种口令都参与加密密钥计算 ;
不设 --upw 时文件仍加密,但任何人都能打开(只是受限),很多工具凭 owner 口令就能解掉限制 —— 所以建议两个都设 。
1 2 3 4 pdfcpu encrypt --opw opw test.pdf pdfcpu encrypt --upw upw --opw opw test.pdf pdfcpu encrypt test.pdf enc.pdf --opw opw --mode aes --key 40 pdfcpu encrypt test.pdf enc.pdf --upw upw --opw opw --mode rc4 --key 128 --perm all
1 2 3 4 5 await pdf.EncryptAsync("test.pdf" , "enc.pdf" , new PdfCpuEncryptOptions { Mode = PdfCpuEncryptionMode.Aes, KeyLength = 256 , UserPassword = "upw" , OwnerPassword = "opw" });
10.2 decrypt — 解密 1 pdfcpu decrypt inFile [outFile] [flags]
1 2 pdfcpu decrypt -upw upw in.pdf out.pdf pdfcpu decrypt -opw opw in.pdf out.pdf
1 2 await pdf.DecryptAsync("in.pdf" , "out.pdf" , new PdfCpuOptions { UserPassword = "upw" });
10.3 changeupw / changeopw — 改口令 1 2 pdfcpu changeupw inFile upwOld upwNew [flags] # 需 --opw pdfcpu changeopw inFile opwOld opwNew [flags] # 需 --upw(首次改时用用户口令)
1 2 pdfcpu changeupw -opw opw in.pdf old new pdfcpu changeopw -upw upw in.pdf old new
1 2 3 4 await pdf.ChangeUserPasswordAsync("in.pdf" , "old" , "new" , new PdfCpuOptions { OwnerPassword = "opw" }); await pdf.ChangeOwnerPasswordAsync("in.pdf" , "old" , "new" , new PdfCpuOptions { UserPassword = "upw" });
10.4 permissions — 访问权限 1 2 pdfcpu permissions list inFile... [flags] pdfcpu permissions set inFile [flags] # --perm + --opw 必需
--perm 取值:
值
含义
none
清空全部权限位(最严格)
all
放开全部权限位
print
仅允许打印
max4Hex
4 位十六进制,逐位精确控制
max12Bits
12 位二进制,逐位精确控制
1 2 3 pdfcpu permissions list in.pdf pdfcpu permissions set --opw opw --perm print in.pdf pdfcpu permissions set --opw opw --perm all in.pdf
1 2 3 4 5 await pdf.PermissionsListAsync(new [] { "in.pdf" });await pdf.PermissionsSetAsync("in.pdf" , PdfCpuPermissionPreset.Print, options: new PdfCpuOptions { OwnerPassword = "opw" }); await pdf.PermissionsSetAsync("in.pdf" , "max4:f3c0" , options: new PdfCpuOptions { OwnerPassword = "opw" });
10.5 signatures — 数字签名 1 2 pdfcpu signatures validate inFile [flags] pdfcpu signatures remove inFile [outFile] [flags]
validate 会校验收到的签名是否被篡改,并输出证据信息(签名者、时间、证书链、是否被修改)。
1 2 pdfcpu signatures validate signed.pdf pdfcpu signatures remove signed.pdf unsigned.pdf
1 2 await pdf.SignaturesValidateAsync("signed.pdf" );await pdf.SignaturesRemoveAsync("signed.pdf" , "unsigned.pdf" );
10.6 certificates — 本地信任证书库 1 2 3 4 pdfcpu certificates list [--json] pdfcpu certificates inspect inFile pdfcpu certificates import inFile... pdfcpu certificates reset
标准构建初始为空;带 -tags pdfcpu_eutl 构建时会内置 EU Trusted List 快照;
支持 .p7c、.pem、.cer、.crt;
导入证书不等于建立法律有效性 ,只是让 pdfcpu 能做本地信任链检查。
1 2 3 4 pdfcpu certificates list --json pdfcpu certificates inspect root.crt pdfcpu certificates import ca.pem pdfcpu certificates reset
1 2 3 4 await pdf.CertificatesListAsync(json: true );await pdf.CertificatesInspectAsync("root.crt" );await pdf.CertificatesImportAsync(new [] { "ca.pem" });await pdf.CertificatesResetAsync();
11. 表单与字体 1 2 3 4 5 6 7 pdfcpu form list inFile... pdfcpu form remove inFile [outFile] <fieldID|fieldName>... pdfcpu form lock inFile [outFile] [fieldID|fieldName]... pdfcpu form unlock inFile [outFile] [fieldID|fieldName]... pdfcpu form reset inFile [outFile] [fieldID|fieldName]... pdfcpu form export inFile [outFileJSON] pdfcpu form fill inFile inFileJSON [outFile]
推荐工作流 :export → 编辑 value / locked → 删除不想改的字段 → fill。 (fill 只处理 value 和 locked 两个属性;字段可用 id 或 name 定位。)
导出 JSON(真实样例,字段按类型分组):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 { "header" : { "source" : "english.pdf" , "version" : "pdfcpu v0.4.1" } , "forms" : [ { "textfield" : [ { "pages" : [ 1 ] , "id" : "30" , "name" : "firstName1" , "default" : "Joe" , "value" : "Jackie" , "multiline" : false , "locked" : false } ] , "datefield" : [ { "pages" : [ 1 ] , "id" : "33" , "name" : "dob1" , "format" : "dd.mm.yyyy" , "value" : "31.12.1999" , "locked" : true } ] , "checkbox" : [ { "pages" : [ 1 ] , "id" : "34" , "name" : "cb11" , "default" : false , "value" : true , "locked" : false } ] , "radiobuttongroup" : [ { "pages" : [ 1 ] , "id" : "35" , "name" : "gender1" , "options" : [ "female" , "male" , "non-binary" ] , "value" : "non-binary" } ] , "combobox" : [ { "pages" : [ 1 ] , "id" : "36" , "name" : "city12" , "editable" : false , "options" : [ "London" , "Sidney" ] , "value" : "Sidney" } ] , "listbox" : [ { "pages" : [ 1 ] , "id" : "37" , "name" : "city11" , "multi" : true , "options" : [ "San Francisco" , "Vienna" ] , "values" : [ "Vienna" ] } ] } ] }
填充时只需保留要改的字段:
1 2 3 4 5 6 7 8 { "forms" : [ { "textfield" : [ { "name" : "firstName" , "value" : "Horst" , "locked" : false } ] , "datefield" : [ { "name" : "dob" , "value" : "31.12.1999" , "locked" : true } ] } ] }
1 2 3 4 pdfcpu form list form.pdf pdfcpu form export form.pdf data.json pdfcpu form fill form.pdf data.json filled.pdf pdfcpu form lock form.pdf locked.pdf dob
1 2 3 4 await pdf.FormListAsync(new [] { "form.pdf" });await pdf.FormExportAsync("form.pdf" , "data.json" );await pdf.FormFillAsync("form.pdf" , "data.json" , "filled.pdf" );await pdf.FormLockAsync("form.pdf" , "locked.pdf" , new [] { "dob" });
若填充后字段显示异常,可在配置里打开 needAppearances: true(pdfcpu 默认已生成外观流)。
11.2 fonts — 字体 1 2 3 pdfcpu fonts list pdfcpu fonts install fontFiles... pdfcpu fonts cheatsheet fontFiles...
list:列出已安装的用户字体(stamp / watermark 的 fontname 从这里取);
install:安装用户字体;
cheatsheet:为指定字体生成字形速查表 PDF。
1 2 pdfcpu fonts list pdfcpu fonts install /usr/share/fonts/truetype/noto/NotoSansCJKsc-Regular.otf
1 2 await pdf.FontsListAsync();await pdf.FontsInstallAsync(new [] { "NotoSansCJKsc-Regular.otf" });
附录 A:C# 封装方法速查表
约定:opt = PdfCpuOptions(含 Pages / UserPassword / OwnerPassword / Verbosity / Quiet / ExtraFlags);ct = CancellationToken。
CLI
C# 方法
validate
ValidateAsync(file) / ValidateAsync(file, mode) / ValidateAsync(files, opt?)
optimize
OptimizeAsync(in, out?, PdfCpuOptimizeOptions?, opt?)
merge
MergeAsync(out, files) / MergeAsync(out, files, PdfCpuMergeOptions?, opt?)
split
SplitAsync(in, outDir) / SplitAsync(in, outDir, mode, pageSel?, opt?)
trim
TrimAsync(in, pages, out?, opt?)
rotate
RotateAsync(in, degrees, out?, opt?)
collect
CollectAsync(in, out?, opt?)
crop
CropAsync(desc, in, out?, opt?)
resize
ResizeAsync(desc, in, out?, opt?)
zoom
ZoomAsync(desc, in, out?, opt?)
info
InfoAsync(file, opt?) / InfoAsync(files, opt?)
version / paper / selectedpages
VersionAsync() / PaperAsync() / SelectedPagesAsync()
config list / reset
ConfigListAsync() / ConfigResetAsync()
import
ImportAsync(out, imageFiles, desc?, opt?)
nup
NUpAsync(out, n, inputs, desc?, opt?)
grid
GridAsync(out, rows, cols, inputs, desc?, opt?)
ndown
NDownAsync(n, in, outDir, out?, desc?, opt?)
booklet
BookletAsync(out, n, inputs, desc?, opt?)
poster
PosterAsync(desc, in, outDir, out?, opt?)
cut
CutAsync(desc, in, outDir, out?, opt?)
create
CreateAsync(jsonFile, out, in?, opt?)
extract
ExtractAsync(in, outDir, PdfCpuExtractMode, opt?)
images list/extract/update
ImagesListAsync / ImagesExtractAsync / ImagesUpdateAsync
pages insert/remove
PagesInsertAsync(in, out?, desc?, opt?) / PagesRemoveAsync(in, pages, out?, opt?)
stamp add/update/remove
StampAddAsync / StampUpdateAsync / StampRemoveAsync
watermark add/update/remove
WatermarkAddAsync / WatermarkUpdateAsync / WatermarkRemoveAsync
attachments *
AttachmentsListAsync / AddAsync / RemoveAsync / ExtractAsync
portfolio *
PortfolioListAsync / AddAsync / RemoveAsync / ExtractAsync
annotations list/remove
AnnotationsListAsync / AnnotationsRemoveAsync
bookmarks *
BookmarksListAsync / ImportAsync / ExportAsync / RemoveAsync
boxes list/add/remove
BoxesListAsync / BoxesAddAsync / BoxesRemoveAsync
keywords *
KeywordsListAsync / AddAsync / RemoveAsync
properties *
PropertiesListAsync / AddAsync / RemoveAsync
pagelayout *
PageLayoutListAsync / SetAsync(layout) / ResetAsync
pagemode *
PageModeListAsync / SetAsync(mode) / ResetAsync
viewerpref *
ViewerPreferencesListAsync / SetAsync(jsonOrString) / ResetAsync
encrypt / decrypt
EncryptAsync(in, out?, PdfCpuEncryptOptions?, perm, opt?) / DecryptAsync
changeupw / changeopw
ChangeUserPasswordAsync / ChangeOwnerPasswordAsync
permissions list/set
PermissionsListAsync / PermissionsSetAsync(in, preset|string, out?, opt?)
signatures remove/validate
SignaturesRemoveAsync / SignaturesValidateAsync
certificates *
CertificatesListAsync(json) / InspectAsync / ImportAsync / ResetAsync
form *
FormListAsync / RemoveAsync / LockAsync / UnlockAsync / ResetAsync / ExportAsync / FillAsync
fonts *
FontsListAsync / FontsInstallAsync / FontsCheatSheetAsync
枚举一览
枚举
成员
PdfCpuValidationMode
Strict、Relaxed
PdfCpuMergeMode
Create、Append、Zip
PdfCpuSplitMode
Span、Bookmark、Page
PdfCpuExtractMode
Image、Font、Content、Page、Meta
PdfCpuStampMode
Text、Image、Pdf
PdfCpuEncryptionMode
Rc4、Aes
PdfCpuPermissionPreset
None、All、Print
PdfCpuPageLayout
SinglePage、OneColumn、TwoColumnLeft、TwoColumnRight、TwoPageLeft、TwoPageRight
PdfCpuPageMode
UseNone、UseOutlines、UseThumbs、FullScreen、UseOC、UseAttachments
PdfCpuVerbosity
Normal、Verbose、VeryVerbose
附录 B:常见坑与最佳实践 B.1 参数转义(写封装时最容易踩) 不要简单地 arg.Replace("\"", "\\\"") 加引号:
Windows 需按 CommandLineToArgvW 规则处理,路径结尾的反斜杠(C:\out\)会把闭合引号吃掉,导致整行参数错位;
Linux / macOS 不该用反斜杠转义,应改用单引号包裹(内部的 ' 写成 '\'')。
封装中已按平台分别处理(EscapeWindows / EscapeUnix)。
B.2 -- 分隔符 stamp、watermark、crop、resize、zoom、cut、poster、import、nup、grid、ndown、booklet、pages insert 这些带 description 的命令,description 可能以 - 开头。统一在位置参数前输出 -- ,否则会被当成 flag。封装已内置(ArgsBuilder.Terminator())。
B.3 中文水印乱码 / 方框 默认字体 Helvetica 只有 Latin 字形。解决:
pdfcpu fonts install /path/NotoSansCJKsc-Regular.otf 安装中文字体;
stamp/watermark 的 description 里用 fontname 指向它,并配合 points + 绝对缩放 (sc:... abs);
CJK 场景可试用 scriptname 避免嵌入字体;
确保传入字符串是 UTF-8。
B.4 扫描件上水印看不见 整页位图会盖住背景层。改用 stamp + op:0.3 模拟水印:
1 pdfcpu stamp add -m text -- 'Draft' 'points:48, scale:1, fillc:.8 .8 .4, op:.3' in.pdf out.pdf
B.5 默认旋转不是 0 stamp/watermark 默认 diagonal:1(沿左下→右上对角线排布),很多人以为默认是 0 度。想要水平文字/图片,显式写 rot:0 。
B.6 参数前缀歧义 d: 这类短前缀可能同时匹配多个参数(import 中的 dim / dpi),报 ambiguous parameter prefix 时改用完整名(dimensions / formsize / dpi)。
B.7 别重复 optimize merge、stamp、watermark、trim、rotate 的输出已是处理过的 PDF,后面再叠 optimize 通常没必要。
B.8 口令会暴露在进程列表 --upw/--opw 明文出现在命令行。生产环境建议:改用 Go API / 隔离执行环境 / 或至少确保进程列表不可被其他用户读取。
B.9 报 bug 的正确姿势 1 pdfcpu validate -vv <file.pdf>
把命令、-vv 输出、可分享的样例 PDF 一起提交 issue。
B.10 参考链接
本文链接: https://blog.hisene.com/2026/09/08/pdfcpu手册/