2

我有一个应用程序的想法,该应用程序将获取一些包含图形和图像(如各种几何形状和多边形)以及一些随机图像并将它们转换为 PDF 的 Flash 内容。

此外,由于我设想这个应用程序将被我的多个用户使用,我希望这个过程快速且可扩展。我能想到的一种可能的解决方案是拥有一个能够组装上述图形和图像的小型 Flash 客户端。生成某种 XML,将其发送到运行 Java 进程的服务器,该进程可以使用 iText 呈现 PDF。

我想知道其他可能的方法或最佳实践是什么。技术不是问题;开源或商业。

我了解图片上传等需要不同的时间,因此请考虑图片随时可用。以下是我在 PDF 渲染解决方案中寻找的标准:

  1. 因为 PDF 渲染引擎,所以对 flash 客户端没有限制。
  2. 可扩展到多个用户
  3. 速度和效率
  4. 最少的序列化/反序列化

如果您能分享您的技术堆栈想法,我将不胜感激。非常感谢!

PS:如果您没有陷入我的 Flash >> XML >> Java 方法的困境,我将不胜感激。我相信这是可以采取的众多方法之一。

4

4 回答 4

3

如果使用 Flash 在浏览器中生成 PDF 是一种选择,则考虑使用 AlivePdf。如果没有,请查看 XSL:FO,我们使用它来将服务器端转换为 PDF。

于 2010-12-31T13:54:56.930 回答
1

我相信 iText 在 Java 代码中生成 PDF。它可能会也可能不会使用 XML 作为其数据源;POJO 也可以。

另一种方式是 XSL-FO。它需要一个 XML 数据源和一个 XSL-FO 样式表来转换 XML 并生成 PDF。Apache 的 Xalan(或任何其他 XSL-T 库)可以为您完成。

“快速”和“可扩展”可能需要的不止这些。上传大量图像是一个有自己的时间尺度和优化的过程,与 PDF 无关。

于 2010-12-31T13:54:32.353 回答
1

PHP有pdflibFPDF(也适用于 PHP)。

于 2010-12-31T13:57:57.137 回答
0

所以你也愿意考虑其他客户?听起来您有一个儿童绘画应用程序,并且想要生成一些可以保留他们当时绘画状态的东西。

让我们面对现实吧,XML 并不是那么高效。这不是它的目的。它是机器和人类可读、可验证等的。

<Canvas>相反,一个以 JSON 格式将画布状态提交给服务器的基于网页的网页怎么样(更少的字节,构建它们的工作也更少)。然后,服务器可以使用它想要的任何地狱库/语言工作。大量的 JSON->my-language 库漂浮在那里。

您在 PDF 库中的选择仅受您在服务器上安装的内容的限制。你还说你想尽可能少地读/写。

最有效的可能设置是将只读部分 PDF 加载到内存中,以最大限度地减少画布更改(包括图像)的影响。每个会话都会复制该部分 PDF,将 JSON 转换为 PDF 图形命令,然后保存 PDF。

为了最大限度地减少对 PDF 的结构更改,您需要使用内联图像。PDF 中没有新对象意味着您根本不需要更改交叉引用表(直到您添加字体或想要重用现有图像)。您可以构建“文档信息”字典,并在对象之间填充特定数量的空格,这样您就可以在不更改任何字节偏移量的情况下填充它(这将迫使您重新计算外部参照表)。

您可能需要也可能不需要弄乱页面大小......我们只是在这里谈论一页,对吧?

所以PDF看起来像......

%%PDF-1.6
<3-4 random high order bytes to convince folks that we're a binary stream>
1 0 obj
<</Type/Catalog/Pages 2 0 R>>
endobj
2 0 obj
<</Type/Pages/Count 1/Kids[3 0 R]>>
endobj
3 0 obj
<</Type/Page/Contents 4 0 R/MediaBox[0 0 612 792]/Parent 2 0 R>>
endobj
5 0 obj
<</Type/DocInfo/Author()  --<insert big whitespace gap here>-- 
/Title() --<ditto>--
/Subject() --<ditto>--
/Keywords() --<ditto>--
/Creator(My app's Name)
/Producer(My pdf library's name)
/CreationDate(encodedDateWhenThisTemplateWasBuilt) D:YYYYMMDDHHMMSS-timeZoneOffset
/ModDate() --<another, smaller whitespace gap>--
>>
4 0 obj
<</Filter/SeveralDifferentFiltersAvailable/Length --<byte length of the stream in this file>-->>
stream

你的模板就停在那里。你会有一个类似的“PDF 结尾”模板,看起来像这样:

endstream
endobj
xref
0 6
0000000000 65535 f 
0000000010 00000 n
0000000025 00000 n
0000000039 00000 n
0000000097 00000 n
0000000050 00000 n
trailer
<</Root 1 0 R/Size 6/Info 5 0 R>>
startxref
--<some white space>--
%%EOF

最后的数字列都是错误的。第一列是该特定对象的字节偏移量(我现在不打算计算字节,谢谢)。第二列在很大程度上无关紧要。

PDF 填写应用程序需要知道:

  1. 您打算在第一个模板中填写的所有内容的字节偏移量。
    1. 顺便说一下,所有“文档信息”字段都是可选的。/Info 键和它指向的字典是可选的。如果你愿意的话,你可以拉他们。
    2. 内容流的 /Length 键。这需要是流本身的过滤后字节长度。
  2. 如何将 JSON 转换为 pdf 绘图命令。如果您想作弊,您可以使用 iText[Sharp] 的 PdfContentByte 类,使用它的绘图命令,然后获取完成的字节流并将其添加到您的 PDF 中。确保您使用内联图像,否则整个方案都会出现在窗外。如果您觉得需要,可能还有其他类似的库。或者,您可以阅读 PDF 规范并自行编写。您将坚持使用相当有限的 PDF 内容语法子集。
  3. 单词“xref”从文件开头的字节偏移量。您可以计算:LengthOfInitialTemplate + LengthOfContentStream + OffsetFromStartOf2ndTemplateTo'xref'。
  4. “startxref”下方行的字节偏移量,这是您写入“xref”的预先计算的字节偏移量的地方

你不会比这更有效率。你曾经读过你的模板。读取/计算一次您需要的字节偏移量。

于 2010-12-31T17:56:30.053 回答