如何在现有PDF中嵌入字体?

背景:

我有PDF,我是以编程方式生成的。 我需要能够从服务器(而不是通过中间应用程序)将PDF直接发送到打印机。 目前我可以完成以上所有操作(生成PDF,发送到打印机),但由于字体未嵌入PDF中,因此打印机正在进行字体替换。

生成时为什么不嵌入字体:

我正在使用SQL Reporting Services 2008创建PDF .SQL Reporting Services存在一个已知问题,即它不会嵌入字体(除非满足一系列要求 – http://technet.microsoft.com/en-us/library /ms159713%28SQL.100%29.aspx )。 不要问我为什么,PDF符合MS列出的所有要求,并且字体仍然显示为未嵌入 – 没有真正控制字体是否嵌入,所以我已经接受这不起作用并继续前进。 Microsoft建议的解决方法( http://blogs.msdn.com/b/donovans/archive/2007/07/20/reporting-services-pdf-renderer-faq.aspx “何时将使用Reporting Services进行字体嵌入”)是发布处理PDF以手动嵌入字体。

目标获取已生成的PDF文档,以编程方式“打开”它并嵌入字体,重新保存PDF。

方法我指向iTextSharp,但大多数示例都是针对Java版本的,我在转换到iTextSharp版本时遇到问题(我找不到iTextSharp的任何文档)。

我正在撰写这篇文章以了解我需要做的事情: Itext将字体嵌入PDF中 。

但是对于我的生活,我似乎无法使用ByteArrayOutputStream对象。 它似乎无法找到它。 我已经研究过并且研究过但似乎没有人说出它在哪个类或我找到它的位置所以我可以将它包含在using语句中。 我甚至破解了开放的Reflector,似乎无法在任何地方找到它。

这是我到目前为止,它编译等等。(结果是我生成的PDF的字节[])。

PdfReader pdf = new PdfReader(result); BaseFont unicode = BaseFont.CreateFont("Georgia", BaseFont.IDENTITY_H, BaseFont.EMBEDDED); // the next line doesn't work as I need a ByteArrayOutputStream variable to pass in PdfStamper stamper = new PdfStamper(pdf, MISSINGBYTEARRAYOUTPUTSTREAMVARIABLE); stamper.AcroFields.SetFieldProperty("test", "textfont", unicode, null); stamper.Close(); pdf.Close(); 

那么有人可以帮我使用iTextSharp将字体嵌入到PDF中或指向正确的方向吗?

我非常乐意使用除iTextSharp之外的任何其他解决方案来完成此目标,但它需要是免费的,并且能够被企业用于内部应用程序(即Affero GPL)。

这可能不是您正在寻找的答案(因为您希望以编程方式解决问题,而不是通过外部工具)。

但是您可以使用Ghostscript命令行将丢失的字体嵌入到未嵌入它们的PDF中:

 gs \ -sFONTPATH=/path/to/fonts:/another/dir/with/more/fonts \ -o output-pdf-with-embedded-fonts.pdf \ -sDEVICE=pdfwrite \ -dPDFSETTINGS=/prepress \ input-pdf-where-some-fonts-are-not-embedded.pdf 

一个重要的是丢失的字体在-sFontPath=...开关指向的一个目录中都可用。

除了Ghostscript之外,还可以使用Poppler和Cairo。 Poppler有一个命令pdftocairo ,它通过pdftocairo -pdf input.pdf output.pdf将PDF转换为PDF。 它还考虑在Fontconfig配置文件中设置的字体替换。 如果您的系统上没有PDF文件中引用的所有字体,但是知道您安装的其他字体是一个好看的替代品,这将非常有用。 处理后,嵌入替换字体。