2010-11-20 71 views
23

背景:如何在現有的PDF中嵌入字體?

我有PDF的我以編程方式生成。我需要能夠將PDF直接從服務器發送到打印機(而不是通過中間應用程序)。目前,我可以完成上述所有工作(生成PDF,發送到打印機),但由於字體未嵌入PDF,因此打印機正在進行字體替換。

爲什麼時產生的字體沒有嵌入:

我創建PDF的使用SQL Reporting Services的2008年有一個已知的問題與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對象。它似乎無法找到它。我已經研究和研究過,但似乎沒有人說出它在哪個類或哪裏找到它,所以我可以將它包含在使用語句中。我甚至打開了反射器,似乎無法在任何地方找到它。

這是我到目前爲止編寫的等等。 (結果是我生成的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)。

+0

你能給出你需要嵌入的字體的名字嗎? (有些字體的許可證不允許嵌入,並且大多數PDF處理或創建軟件確實遵守字體文件中的相應標誌,並選擇不嵌入T ...) – 2010-11-20 17:28:30

+0

當然!格魯吉亞和Calibri - 我已經檢查過我們有TrueType版本和(根據Windows),他們都將'字體嵌入性'標籤設置爲'可編輯' - 我收集這是正確的設置?謝謝你的幫助! – hanzworld 2010-11-21 02:53:04

+0

對於稍後閱讀此內容的人來說,這兩種方法都有效。 SQL Reporting Services最終在許多更新/修補程序後正確嵌入字體,並可以直接發送到打印機。另外,使用.NET中的ProcessInfo調用Ghostscript可以後處理PDF。 – hanzworld 2011-08-31 00:42:24

回答

29

這可能不是您正在尋找的答案(因爲您希望以編程方式解決您的問題,而不是通過外部工具)。

但是你可以用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=...開關。

+0

嘿,謝謝你 - 我有一個快速去看看這個輸出,輸出PDF確實有嵌入字體 - 但它取代了所有與Helvetica的字體!我無法解決如何糾正這一問題。有任何想法嗎? – hanzworld 2010-11-23 23:59:28

+1

@hanzworld:你能提供'pdffonts.exe original.pdf'和'pdffonts.exe processed.pdf'的輸出嗎? ('pdffonts.exe'是XPDF CLI公用程序的一部分:http://www.foolabs.com/xpdf/download.html – 2010-11-24 22:51:23

+0

原始PDF:名稱類型emb sub sub uni對象ID ------- ---------------- ----------- --- --- --- --------- Calibri TrueType no no否3 0 格魯吉亞,BoldItalic TrueType否否否4 0 Calibri,Bold TrueType否否否5 0 格魯吉亞,斜體TrueType否否否9 0 – hanzworld 2010-11-28 23:00:00

8

除了Ghostscript,還可以使用Poppler和Cairo。Poppler有一個命令pdftocairo,它通過pdftocairo -pdf input.pdf output.pdf將PDF轉換爲PDF。它還考慮在Fontconfig配置文件中設置的字體替換。如果您的系統中沒有引用PDF文件中的所有字體,但是知道您安裝的其他字體是否是一個好看的替代品,這將非常有用。處理後,替換字體被嵌入。

+1

+ 1: - - 嘿,我不知道!:-)現在我會信任它按照你的描述工作。稍後再測試。但如果它不起作用,我將不得不再次拿回我的電話...... :-) – 2014-12-22 17:06:21

+0

這比使用'gs'容易得多 - 我甚至可以記住這個命令。 – fission 2015-06-23 07:06:39

+1

這很好。只需要注意Windows cygwin用戶 - 如果你嘗試在cygwin下運行它,它可能會使用不同的字體來改變圖像的外觀。從標準的命令提示符使用[Poppler for Windows](http://blog.alivate.com.au/poppler-windows/)效果很好。感謝您發佈這個答案。 – zelanix 2016-09-15 09:10:38