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

时间:2010-11-20 07:17:48

标签: c# pdf itextsharp ghostscript embedded-fonts

背景

我有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 embed font in a 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)。

4 个答案:

答案 0 :(得分:31)

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

但是您可以使用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=...开关指向的其中一个目录中缺少所有字体。

答案 1 :(得分:11)

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

答案 2 :(得分:1)

我今天遇到了这个问题,因为我将现有的PDF上传到lulu.com进行打印。由于未嵌入所有字体而被拒绝。

我发现,如果我在Acrobat X中将其打开并另存为Postscript .ps文件,那么当我在File Explorer中双击该.ps文件时,便在Acrobat X Distiller中打开了文件,这会自动创建一个新的PDF文件嵌入所有字体!

自然,这意味着您必须拥有计算机上所需的所有字体。否则,诸如InFix之类的程序可以替换字体。

答案 3 :(得分:0)

我在要提交给IEEE的PDF的Mac上遇到此问题。使用Adobe Reader和Preview,我能够解决这个问题。我认为,如果您在PC上,则任何pdf打印机都可以代替预览。

这是我采取的步骤。您可以单独修复每个图形,也可以修复整个文档。

  1. 使用Adobe Reader打开pdf文件。

  2. 右键单击图像,然后单击“文档属性”。

  3. 单击“字体”。检查字体是否未嵌入。应该说“ Courier”或其他字体名称。

  4. 如果您的pdf不是标准页面尺寸,请单击“说明”并查看页面尺寸。写下来。例如19.4 x 5.22英寸。

  5. 在“预览”中打开pdf。转到文件->打印。如果使用的不是标准页面尺寸的pdf,请点击纸张尺寸,然后选择自定义。您将需要创建一个自定义页面尺寸,该尺寸等于您在第4步中写下的尺寸。不要忘记将所有边距都设为0。之后,您需要在“打印”对话框中将打印比例设置为100%。

  6. 在“打印”对话框的左下角(在Mac上为“预览”),单击“ PDF”将PDF打印为新的PDF。选择目的地并打印。

  7. 在Adobe Reader中打开新的pdf文件,并确认现在已嵌入字体。

我希望这会有所帮助。