使用XFAFlattener嵌入字体展平文档

时间:2015-09-16 08:53:06

标签: itextsharp

我使用XFA_Worker展平现有文档。有没有办法强制字体嵌入拼合文档?

using iText = iTextSharp.text;
using iTextPDF = iTextSharp.text.pdf;
using iTextImage = iTextSharp.text.Image;
using iTextReader = iTextSharp.text.pdf.PdfReader;
using iTextWriter = iTextSharp.text.pdf.PdfWriter;

reader = new iTextReader(tempFileDirectory + "\\" + "orig_" + tmpFileName);

iTextPDF.AcroFields form = reader.AcroFields;
iTextPDF.XfaForm xfa = form.Xfa; 

if (xfa.XfaPresent)
{
    iText.Document document = new iText.Document();
    iTextWriter writer = iTextWriter.GetInstance(document,
        new FileStream(tempFileDirectory + "\\" + tmpFileName, FileMode.Create));

    XFAFlattener xfaf = new XFAFlattener(document, writer);
    xfaf.Flatten(reader);
    document.Close();
    writer.Close();
}

1 个答案:

答案 0 :(得分:2)

对于特定项目,我的HTML需要嵌入常规字体和粗体字体。 PDF的要求也非常严格:我不允许使用除OpenSans和OpenSans粗体以外的任何字体,并且文本必须存储为UNICODE(不允许使用简单字体)。

为了满足这些要求,我编写了FontProvider接口的以下实现:

class MyFontProvider implements FontProvider {

    protected BaseFont regular;
    protected BaseFont bold;

    public MyFontProvider() throws DocumentException, IOException {
        regular = BaseFont.createFont("resources/fonts/OpenSans-Regular.ttf", BaseFont.IDENTITY_H, true);
        bold = BaseFont.createFont("resources/fonts/OpenSans-Bold.ttf", BaseFont.IDENTITY_H, true);
    }

    public boolean isRegistered(String fontname) {
        return true;
    }

    public Font getFont(String fontname, String encoding, boolean embedded, float size, int style, BaseColor color) {
        Font font;
        switch (style) {
            case Font.BOLD:
                font = new Font(bold, size);
                break;
            default:
                font = new Font(regular, size);
        }
        font.setColor(color);
        return font;
    }
}

我在构造函数中创建了两个BaseFont个实例。在getFont()方法中,我忽略了fontnameencodingembedded参数。我将始终使用Identity-H作为"编码"返回嵌入式OpenSans。我会应用字体大小,字体颜色和样式(但仅在样式设置为粗体的情况下;在所有其他情况下,我使用常规字体)。您可以按照自己喜欢的方式调整此FontProvider,但就我而言,这些是对项目的严格要求。

显然,我需要" long" XML Worker代码的版本,因为我现在需要向HTML管道声明MyFontProvider

// CSS
CSSResolver cssResolver = new StyleAttrCSSResolver();
CssFile cssFile = XMLWorkerHelper.getCSS(new FileInputStream(CSS));
cssResolver.addCss(cssFile);

// HTML
CssAppliers cssAppliers = new CssAppliersImpl(new MyFontProvider());
HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());

// Pipelines
PdfWriterPipeline pdf = new PdfWriterPipeline(document, writer);
HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);
CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);

// XML Worker
XMLWorker worker = new XMLWorker(css, true);
XMLParser p = new XMLParser(worker);
p.parse(new ByteArrayInputStream(invoice));

每次XML Worker需要字体时,它都会调用MyFontProvider,而getFont()方法将不会返回除嵌入的OpenSans或OpenSans-Bold之外的其他字体。

XFA Flattener也存在相同的原则,您可以使用CssAppliersFontProvider实现。由于XFA Worker是一个封闭源产品,这意味着您要么使用试用版,要么您是iText Group的客户。在这两种情况下,如果此答案无法解决您的问题,请直接与iText Group联系。