如何生成正确的PDF文件?

问题描述 投票:0回答:1

我制作了一个生成PDF文件的程序。这些文件相当简单——文本(CID 类型 2)、矢量图形、图像、流过滤器。当我在 Adobe Reader 中打开我的程序生成的文件时,它看起来没问题。但是当我关闭它时,读者会询问我是否要保存对文件所做的更改,即使我没有进行任何更改。我使用 Adobe Reader XI。正如我所读到的,这通常发生在文件损坏时。


尝试了一些实验。

我创建了“简单文本字符串示例”,如文档中所述(使用记事本和十六进制编辑器)。这很好用。但后来我添加了一条评论,并在关闭时显示了保存对话框。显然,带有注释的文件不可能被损坏,而没有注释的文件则不会。

然后我使用 MS Word (MS 365) 创建了一个 PDF,并删除了所有不必要的内容。元数据、信息字典、逻辑结构、标记内容、XRef 流……直到文件看起来几乎像我的程序生成的文件。我试图达到读者会给我保存提示的程度。但即使做了所有这些修改,也没有任何提示。

我还尝试在其他 PDF 阅读器(Foxit、Google Chrome、Slim PDF Reader)中打开这些“损坏”的文件,它们似乎对文件没有任何问题。


所以,我有两个问题:

  • Adobe Reader 要求我保存的文件有问题吗?如果是这样的话,
  • 我可以做什么来修复它们? PDF 规范中是否有我可能忽略的“PDF 应满足的最低要求”?
pdf-generation
1个回答
0
投票

“标准”中的示例是假设的,通常无法正常工作,因此我已更正该示例,该示例已被除 Acrobat 之外的所有读者接受,将预告片更改为

xref
0 7
0000000000 65535 f 
0000000009 00000 n 
0000000075 00000 n 
0000000121 00000 n 
0000000181 00000 n 
0000000303 00000 n 
0000000382 00000 n 

trailer
<< /Size 7
/Root 1 0 R
>>
startxref
407
%%EOF

我相信这些值对于我的编辑来说是正确的,因为我使用另外 2 个阅读器来指出预告片中的缺陷/错误。

所以让我们使用他们的“Hello World”示例来更容易地证明差异。 这在所有 3 个阅读器测试中都有效,打开和关闭都没有错误。

%PDF-1.4
1 0 obj
<< /Type /Catalog
/Outlines 2 0 R
/Pages 3 0 R
>>
endobj

2 0 obj
<< /Type Outlines
/Count 0
>>
endobj

3 0 obj
<< /Type /Pages
/Kids [ 4 0 R ]
/Count 1
>>
endobj

4 0 obj
<< /Type /Page
/Parent 3 0 R
/MediaBox [ 0 0 612 792 ]
/Contents 5 0 R
/Resources << /ProcSet 6 0 R
/Font << /F11 7 0 R >>
>>
>>
endobj

5 0 obj
<< /Length 43 >>
stream
BT
/F1 24 Tf
100 100 Td
(Hello World) Tj
ET
endstream
endobj

6 0 obj
[/PDF /Text]
endobj

7 0 obj
<< /Type /Font
/Subtype /Type1
/Name /F1
/BaseFont /Helvetica
/Encoding /MacromanEncoding
>>
endobj

xref
0 8
0000000000 65535 f 
0000000009 00000 n 
0000000075 00000 n 
0000000121 00000 n 
0000000181 00000 n 
0000000326 00000 n 
0000000420 00000 n 
0000000449 00000 n 

trailer
<< /Size 8
/Root 1 0 R
>>
startxref
558
%%EOF

因此需要逐行注意。

  • 所有行均以 Linux 结尾,因此没有“回车”,只有换行符 (0A),在这种情况下没有十六进制
    0D
    (它们会增加每行所需的额外字节)。
  • 所有行都没有缩进(与出版物不同!),但是它们的文本字符串流允许填充!
  • 2 0 Obj 在预告片中的值为 75 不是 74,因此从那时起,XREF 会受到许多其他错误值的影响,这就是 Acrobat 想要重写整个文件的原因!
  • 最后,从图中并不清楚所有以
    n
    结尾的外部参照行在
    n
    之后都包含一个空格字符,因为我们正在工作 without 2 字节行终止符。
© www.soinside.com 2019 - 2024. All rights reserved.