如何在现有 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 建议的解决方法(链接< /a> 在“Reporting Services 何时进行字体嵌入”下)是对 PDF 进行后处理以手动嵌入字体。
目标 获取已生成的 PDF 文档,以编程方式“打开”它并嵌入字体,重新保存 PDF。
方法 我被指向 iTextSharp,但大多数示例都是针对 Java 版本的,我在转换为 iTextSharp 版本时遇到了麻烦(我找不到 iTextSharp 的任何文档)。
我正在写这篇文章来完成我需要做的事情: Itext 在 PDF 中嵌入字体< /a>.
然而,在我的一生中,我似乎无法使用 ByteArrayOutputStream 对象。好像找不到啊我研究了又研究,但似乎没有人说它属于哪个类或我在哪里找到它,所以我可以将它包含在 using 语句中。我什至打开了 Reflector,但似乎无法在任何地方找到它。
这是我到目前为止所拥有的,它可以编译等等。 (结果是我生成的 PDF 的 byte[])。
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)。
Background:
I have PDF's I am programmatically generating. I need to be able to send the PDF directly to a printer from the server (not through an intermediate application). At the moment I can do all of the above (generate PDF, send to printer), but because the fonts aren't embedded in the PDF the printer is doing font substitution.
Why the fonts aren't embedded when generated:
I am creating PDF's using SQL Reporting Services 2008. There is a known issue with SQL Reporting Services in that it will not embed fonts (unless a series of requirements are met - http://technet.microsoft.com/en-us/library/ms159713%28SQL.100%29.aspx). Don't ask me why, the PDF meets all of MS's listed requirements and the fonts still show up as not embedded - there is no real control over whether the fonts are embedded, so I have accepted that this isn't working and moved on. The suggested workaround from Microsoft (Link under 'When will Reporting Services do font embedding') is to post process the PDF to manually embed the fonts.
Goal
Take an already generated PDF document, programmatically 'open' it and embed the fonts, resave the PDF.
Approach
I was pointed towards iTextSharp, but most of the examples are for the Java version and I'm having trouble translating to the iTextSharp version (I can't find any documentation for iTextSharp).
I am working on this post for what I need to do: Itext embed font in a PDF.
However for the life of me, I cannot seem to use the ByteArrayOutputStream object. It can't seem to find it. I've researched and researched but nobody seems to say what class it's in or where I find it so I can include it in the using statements. I've even cracked open Reflector and can't seem to find it anywhere.
This is what I have so far and it compiles etc. etc.
(result is my byte[] of the generated 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();
So can anybody either help me with using iTextSharp to embed fonts into a PDF or point me in the right direction?
I'm more than happy to use any other solutions other than iTextSharp to complete this goal, but it needs to be free and able to be used by a business for an internal application (i.e. Affero GPL).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这可能不是您正在寻找的答案(因为您希望以编程方式解决问题,而不是通过外部工具)。
但是,您可以使用 Ghostscript 命令行将丢失的字体嵌入到尚未嵌入它们的 PDF 中:
一件重要的事情是,丢失的字体都可以在
-sFontPath=...< 指向的目录之一中找到。 /代码> 开关。
This may not be the answer you are looking for (since you want to get your problems solved programmatically, not by an external tool).
But you can use Ghostscript commandline to embed missing fonts in retrospect to PDFs which have not embedded them:
One important thing is that the missing fonts are all available in one of the directories pointed to by the
-sFontPath=...
switch.除了 Ghostscript 之外,还可以使用 Poppler 和 Cairo。 Poppler 有一个命令
pdftocairo
,可以通过pdftocairo -pdf input.pdf output.pdf
将 PDF 转换为 PDF。它还考虑在 Fontconfig 配置文件中设置的字体替换。如果您的系统上没有 PDF 文件中引用的所有字体,但知道您安装的其他字体是好看的替代品,这将非常有用。处理后,嵌入替换字体。Besides Ghostscript, it is also possible to use Poppler and Cairo. There is a command
pdftocairo
from Poppler that converts PDF to PDF viapdftocairo -pdf input.pdf output.pdf
. It also considers font substitutions set in a Fontconfig configuration file. This is very helpful if you do not have all fonts on your system that are referenced in a PDF file, but know which other font you have installed is a good-looking replacement. After processing, the substitution font is embedded.我在 Mac 上使用要提交给 IEEE 的 PDF 时遇到了这个问题。使用 Adobe Reader 和 Preview,我能够解决这个问题。我认为如果您使用的是 PC,任何 pdf 打印机都可以代替预览。
这是我采取的步骤。您可以单独修复每个图形,或修复整个文档。
使用 Adobe Reader 打开 pdf 文件。
右键单击图像,然后单击“文档属性”。
点击“字体”。检查字体是否未嵌入。应该说“Courier”或其他字体名称。
如果您的 pdf 不是标准页面尺寸,请单击“说明”并查看页面尺寸。把这个写下来。前任。 19.4 x 5.22 英寸。
在预览中打开 pdf 文件。转到文件 -> 打印。如果使用的 pdf 不是标准页面尺寸,请单击“纸张尺寸”并选择“自定义”。您需要创建一个等于您在步骤 4 中记下的页面大小的自定义页面大小。不要忘记将所有边的边距均为零。完成此操作后,您需要在打印对话框中将打印比例设置为 100%。
在打印对话框的左下角(在 Mac 上为“预览”),单击“PDF”将 PDF 打印为新的 PDF。选择目标位置并打印。
在 Adobe Reader 中打开新的 pdf 并验证字体现已嵌入。
我希望这有帮助。
I had this problem on a Mac with a PDF I was submitting to IEEE. Using Adobe Reader and Preview, I was able to get around this. I think any pdf printer might work in place of Preview if you are on a PC.
Here are the steps I took. You can individually fix each figure, or fix the whole document.
Open at pdf file using Adobe Reader.
Right click on image, and click “Document Properties.”
Click “Fonts.” Check to see if the font isn’t embedded. Should say “Courier” or other font name.
If your pdf isn’t a standard page size, click on “Description” and look at the page size. Write this down. Ex. 19.4 x 5.22 in.
Open the pdf up in Preview. Go to File->Print. If using a pdf that isn’t a standard page size, click on Paper Size and choose custom. You will need to create a custom page size that is equal to the one you wrote down in step 4. Don’t forget to zero the margins to 0 for all sides. After doing that, you’ll need to set the scale of the print in the print dialog to 100%.
In the lower left of the print dialog (in Preview on a Mac), click “PDF” to print the PDF to a new PDF. Select the destination and print.
Open the new pdf up in Adobe Reader and verify that the fonts are now embedded.
I hope this helps.
我今天在上传到 lulu.com 制作打印副本的现有 PDF 时遇到了这个问题。由于未嵌入所有字体而被拒绝。
我发现,如果我在 Acrobat X 中打开它并保存为 postscript .ps 文件,那么当我在文件资源管理器中双击该 .ps 文件时,它会在 Acrobat X Distiller 中打开,并且这会自动创建一个包含所有字体的新 PDF 文件嵌入!
当然,这意味着您必须拥有计算机上所需的所有字体。否则,像 InFix 这样的程序可以进行字体替换。
I had this problem today with an existing PDF I uploaded to lulu.com to make a printed copy. It was rejected for not having all fonts embedded.
I found that if I opened it in Acrobat X and Saved out as postscript .ps file, then when I double clicked this .ps file in File Explorer, it opened in Acrobat X Distiller, and this automatically created a new PDF file with all fonts embedded!
Naturally this would mean you must have all the fonts needed on your computer. Otherwise a program like InFix can make font substitutions.
如果您足够幸运(或富有)拥有 Adobe Acrobat(而不是阅读器),您可以这样做:打开文件,另存为 PDF/A。如果您希望文件可编辑,可以立即单击“启用编辑”并再次保存。
If you are lucky (or rich) enough to own Adobe Acrobat (not the reader), you can do it like this: Open the file, save as PDF/A. If you want the file to be editable, you can immediately click on "Enable editing" and save again.