手动创建交互式 PDF
Manually creating interactive PDFs
由于难以解释的原因,我需要在不使用任何第三方库的情况下从 C# 应用程序创建简单的 PDF。相关 PDF 需要包含文本和线条图,如果可能,还应包含图像、单选按钮和文本字段。我一直在阅读 Adobe 的 documentation,它在很大程度上是直截了当的,但到目前为止还无法弄清楚如何使交互式字段真正出现在文档上。
例如,考虑下面描述的部分测试 PDF 文档:
1 0 obj
<< /Type /Catalog
/Pages 2 0 R
/AcroForm 6 0 R
>>
endobj
...
6 0 obj
<< /Fields [ 7 0 R ]
/DR 5 0 R
>>
endobj
7 0 obj
<< /FT /Btn
/Ff 65536
/Kids [ 8 0 R 9 0 R ]
>>
endobj
8 0 obj
<< /Parent 7 0 R
/AS /FieldA
/AP 10 0 R
>>
endobj
9 0 obj
<< /Parent 8 0 R
/AS /FieldB
/AP 10 0 R
>>
endobj
10 0 obj
<< /N
<< /FieldA 11 0 R
/FieldB 12 0 R
/Off 13 0 R
>>
>>
endobj
11 0 obj
<< /Length 59 >>
stream
BT
/F1 12 Tf
0 0 Td
(Field A) Tj
ET
endstream
endobj
...
其中 5 0 R
引用包含字体 /F1
和 12 0 R
的资源字典,并且 13 0 R
引用类似于 11 0 R
的流,其中字符串替换为 Field B
和 Off
分别。
我需要对文档进行哪些更改才能使如此定义的字段实际出现在页面上?
编辑:由于 mkl 的要求,这里是整个 pdf(为保存而删除了额外的换行符 space)
%PDF-1.7
%¥±ë
1 0 obj << /Type /Catalog /Pages 2 0 R >> endobj
2 0 obj << /Type /Pages /Kids [3 0 R] /Count 1 /MediaBox [0 0 200 200] >> endobj
3 0 obj << /Type /Page /Parent 2 0 R /Resources 5 0 R /Contents 4 0 R >> endobj
4 0 obj << /Length 39 >>
stream
BT /F1 12 Tf 0 0 Td (Hello World) Tj ET
endstream
endobj
5 0 obj << /Font << /F1 << /Type /Font /Subtype /Type1 /BaseFont /Helvetica >> >> >> endobj
6 0 obj << /Fields [ 7 0 R ] /DR 5 0 R >> endobj
7 0 obj << /FT /Btn /Ff 65536 /Kids [ 8 0 R 9 0 R ] >> endobj
8 0 obj << /Parent 7 0 R /AS /FieldA /AP 10 0 R >> endobj
9 0 obj << /Parent 7 0 R /AS /FieldB /AP 10 0 R >> endobj
10 0 obj << /N << /FieldA 11 0 R /FieldB 12 0 R /Off 13 0 R >> >> endobj
11 0 obj << /Length 59 >>
stream
BT /F1 12 Tf 0 0 Td (Field A) Tj ET
endstream
endobj
12 0 obj << /Length 39 >>
stream
BT /F1 12 Tf 0 0 Td (Field B) Tj ET
endstream
endobj
13 0 obj << /Length 39 >>
stream
BT /F1 12 Tf 0 0 Td (Off... ) Tj ET 94
endstream
endobj
xref
0 14
0000000000 65535 f
0000000018 00000 n
0000000068 00000 n
0000000150 00000 n
0000000233 00000 n
0000000327 00000 n
0000000420 00000 n
0000000470 00000 n
0000000533 00000 n
0000000592 00000 n
0000000651 00000 n
0000000727 00000 n
0000000821 00000 n
0000000917 00000 n
trailer << /Root 1 0 R /Size 5 >>
startxref
1013
%%EOF
您的字段将需要包含所谓的 "appearances",即包含用于创建字段视觉外观的绘图指令的 XObject。请参阅 PDF 规范的第 12.5.5 节。或者,您可以将文档目录中 AcroForm 条目的 NeedAppearances 属性 设置为 true。请参阅 PDF 规范的第 12.7.2 节。将此设置为 true 将导致一致的查看器根据字段的属性创建字段的外观。但是,您不能指望大多数观众会这样做。
根据您发布的完整文件,我发现了几个问题(可能还有更多):
- 文档目录不包含 /AcroForm 条目
- 该页面不包含带有字段小部件链接的 /Annots 条目
- 字段定义 8 和 9 不完整,它们不包括小部件注释条目。这些条目指定页面上的字段位置
- 您的字段是一个按钮,它没有不同的外观状态,/N 外观应该是对外观流(11、12 或 13)的引用
- 字段外观 11、12、13 无效,/Type、/Subtype、/BBox、/Resources 等条目缺失
更新:您可以在下面找到单选按钮的最小文件结构。
1 0 obj
<< /Type /Catalog /Version /1.4 /Pages 8 0 R /AcroForm <</Fields [2 0 R ]>> >>
endobj
2 0 obj
<< /FT /Btn /T (Radio) /V /Off /Kids [5 0 R 3 0 R ] /Ff 32768 >>
endobj
3 0 obj
<< /Type /Annot /F 4 /Rect [250 667 270 687 ] /Subtype /Widget /AS /Off /AP << /N << /Two 7 0 R /Off 6 0 R >> >> /Parent 2 0 R /P 4 0 R >>
endobj
4 0 obj
<< /Type /Page /Contents null /MediaBox [0 0 612 792 ] /Parent 8 0 R /Annots [5 0 R 3 0 R ] >>
endobj
5 0 obj
<< /Type /Annot /F 4 /Rect [150 667 170 687 ] /Subtype /Widget /AS /Off /AP << /N << /One 7 0 R /Off 6 0 R >> >> /Parent 2 0 R /P 4 0 R >>
endobj
6 0 obj
<< /Type /XObject /Subtype /Form /BBox [0 0 20 20 ] /Length 74 >>
stream
/DeviceRGB CS 0 0 0 SC 1 w 0.5 0.5 m 19.5 0.5 l 19.5 19.5 l 0.5 19.5 l h S
endstream
endobj
7 0 obj
<< /Type /XObject /Subtype /Form /BBox [0 0 20 20 ] /Length 55 >>
stream
/DeviceRGB cs 0 0 0 sc 0 0 m 20 0 l 20 20 l 0 20 l h f
endstream
endobj
8 0 obj
<< /Type /Pages /Count 1 /Kids [4 0 R ] >>
endobj
您可以下载minimum radio button sample and a more detailed radio button sample。
使用我们的 XFINIUM.PDF Inspector 您可以可视化 PDF 文件结构。
由于难以解释的原因,我需要在不使用任何第三方库的情况下从 C# 应用程序创建简单的 PDF。相关 PDF 需要包含文本和线条图,如果可能,还应包含图像、单选按钮和文本字段。我一直在阅读 Adobe 的 documentation,它在很大程度上是直截了当的,但到目前为止还无法弄清楚如何使交互式字段真正出现在文档上。
例如,考虑下面描述的部分测试 PDF 文档:
1 0 obj
<< /Type /Catalog
/Pages 2 0 R
/AcroForm 6 0 R
>>
endobj
...
6 0 obj
<< /Fields [ 7 0 R ]
/DR 5 0 R
>>
endobj
7 0 obj
<< /FT /Btn
/Ff 65536
/Kids [ 8 0 R 9 0 R ]
>>
endobj
8 0 obj
<< /Parent 7 0 R
/AS /FieldA
/AP 10 0 R
>>
endobj
9 0 obj
<< /Parent 8 0 R
/AS /FieldB
/AP 10 0 R
>>
endobj
10 0 obj
<< /N
<< /FieldA 11 0 R
/FieldB 12 0 R
/Off 13 0 R
>>
>>
endobj
11 0 obj
<< /Length 59 >>
stream
BT
/F1 12 Tf
0 0 Td
(Field A) Tj
ET
endstream
endobj
...
其中 5 0 R
引用包含字体 /F1
和 12 0 R
的资源字典,并且 13 0 R
引用类似于 11 0 R
的流,其中字符串替换为 Field B
和 Off
分别。
我需要对文档进行哪些更改才能使如此定义的字段实际出现在页面上?
编辑:由于 mkl 的要求,这里是整个 pdf(为保存而删除了额外的换行符 space)
%PDF-1.7
%¥±ë
1 0 obj << /Type /Catalog /Pages 2 0 R >> endobj
2 0 obj << /Type /Pages /Kids [3 0 R] /Count 1 /MediaBox [0 0 200 200] >> endobj
3 0 obj << /Type /Page /Parent 2 0 R /Resources 5 0 R /Contents 4 0 R >> endobj
4 0 obj << /Length 39 >>
stream
BT /F1 12 Tf 0 0 Td (Hello World) Tj ET
endstream
endobj
5 0 obj << /Font << /F1 << /Type /Font /Subtype /Type1 /BaseFont /Helvetica >> >> >> endobj
6 0 obj << /Fields [ 7 0 R ] /DR 5 0 R >> endobj
7 0 obj << /FT /Btn /Ff 65536 /Kids [ 8 0 R 9 0 R ] >> endobj
8 0 obj << /Parent 7 0 R /AS /FieldA /AP 10 0 R >> endobj
9 0 obj << /Parent 7 0 R /AS /FieldB /AP 10 0 R >> endobj
10 0 obj << /N << /FieldA 11 0 R /FieldB 12 0 R /Off 13 0 R >> >> endobj
11 0 obj << /Length 59 >>
stream
BT /F1 12 Tf 0 0 Td (Field A) Tj ET
endstream
endobj
12 0 obj << /Length 39 >>
stream
BT /F1 12 Tf 0 0 Td (Field B) Tj ET
endstream
endobj
13 0 obj << /Length 39 >>
stream
BT /F1 12 Tf 0 0 Td (Off... ) Tj ET 94
endstream
endobj
xref
0 14
0000000000 65535 f
0000000018 00000 n
0000000068 00000 n
0000000150 00000 n
0000000233 00000 n
0000000327 00000 n
0000000420 00000 n
0000000470 00000 n
0000000533 00000 n
0000000592 00000 n
0000000651 00000 n
0000000727 00000 n
0000000821 00000 n
0000000917 00000 n
trailer << /Root 1 0 R /Size 5 >>
startxref
1013
%%EOF
您的字段将需要包含所谓的 "appearances",即包含用于创建字段视觉外观的绘图指令的 XObject。请参阅 PDF 规范的第 12.5.5 节。或者,您可以将文档目录中 AcroForm 条目的 NeedAppearances 属性 设置为 true。请参阅 PDF 规范的第 12.7.2 节。将此设置为 true 将导致一致的查看器根据字段的属性创建字段的外观。但是,您不能指望大多数观众会这样做。
根据您发布的完整文件,我发现了几个问题(可能还有更多):
- 文档目录不包含 /AcroForm 条目
- 该页面不包含带有字段小部件链接的 /Annots 条目
- 字段定义 8 和 9 不完整,它们不包括小部件注释条目。这些条目指定页面上的字段位置
- 您的字段是一个按钮,它没有不同的外观状态,/N 外观应该是对外观流(11、12 或 13)的引用
- 字段外观 11、12、13 无效,/Type、/Subtype、/BBox、/Resources 等条目缺失
更新:您可以在下面找到单选按钮的最小文件结构。
1 0 obj
<< /Type /Catalog /Version /1.4 /Pages 8 0 R /AcroForm <</Fields [2 0 R ]>> >>
endobj
2 0 obj
<< /FT /Btn /T (Radio) /V /Off /Kids [5 0 R 3 0 R ] /Ff 32768 >>
endobj
3 0 obj
<< /Type /Annot /F 4 /Rect [250 667 270 687 ] /Subtype /Widget /AS /Off /AP << /N << /Two 7 0 R /Off 6 0 R >> >> /Parent 2 0 R /P 4 0 R >>
endobj
4 0 obj
<< /Type /Page /Contents null /MediaBox [0 0 612 792 ] /Parent 8 0 R /Annots [5 0 R 3 0 R ] >>
endobj
5 0 obj
<< /Type /Annot /F 4 /Rect [150 667 170 687 ] /Subtype /Widget /AS /Off /AP << /N << /One 7 0 R /Off 6 0 R >> >> /Parent 2 0 R /P 4 0 R >>
endobj
6 0 obj
<< /Type /XObject /Subtype /Form /BBox [0 0 20 20 ] /Length 74 >>
stream
/DeviceRGB CS 0 0 0 SC 1 w 0.5 0.5 m 19.5 0.5 l 19.5 19.5 l 0.5 19.5 l h S
endstream
endobj
7 0 obj
<< /Type /XObject /Subtype /Form /BBox [0 0 20 20 ] /Length 55 >>
stream
/DeviceRGB cs 0 0 0 sc 0 0 m 20 0 l 20 20 l 0 20 l h f
endstream
endobj
8 0 obj
<< /Type /Pages /Count 1 /Kids [4 0 R ] >>
endobj
您可以下载minimum radio button sample and a more detailed radio button sample。
使用我们的 XFINIUM.PDF Inspector 您可以可视化 PDF 文件结构。