当前位置: 首页 > 面试题库 >

如何在iText XMLWorker中摆脱Helvetica?

慎兴业
2023-03-14
问题内容

我们正在使用iText从Java代码生成PDF文件,该文件在大多数情况下效果很好。几天前,我们开始生成PDF /
A,而不是需要嵌入所有字体的普通PDF文件。iText
Document主要是自定义PdfPTable类和其他类的构建,在这些类中我们直接控制字体。所有使用的字体都是通过通过以下代码加载的TTF文件创建的-
效果很好:

    private BaseFont load(String path) {
        try {
            URL fontResource = PrintSettings.class.getResource(path);
            if (fontResource == null) {
                return null;
            }
            String fontPath = fontResource.toExternalForm();
            BaseFont baseFont = BaseFont.createFont(fontPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
            baseFont.setSubset(true);
            return baseFont;
        }
        catch (DocumentException ex) {
            Logger.getLogger(PrintSettings.class).warn("...");
        }
        catch (IOException ex) {
            Logger.getLogger(PrintSettings.class).warn("...");
        }
        return FontFactory.getFont(PrintSettings.FONT, "UTF-8", true, 8f, Font.NORMAL, PrintSettings.COLOR_TEXT).getBaseFont();
    }

现在,我们在使用HTML代码生成的PDF中使用一种特定的内容类型。我们使用XMLWorker来处理该部分。只要我们不嵌入字体,它就可以正常工作。但是,使用PDF
/ A,我们 需要 嵌入所有字体,现在我们正 面临着 使用 Helvetica 的未知来源的困扰。

我们试图通过使用我们自己的 FontProvider 类来解决此问题,如下所示:

public class PrintFontProvider extends FontFactoryImp {

    @Override
    public Font getFont(String fontName, String encoding, boolean embedded, float size, int style, BaseColor color, boolean cached) {

        // LiberationSans – http://de.wikipedia.org/wiki/Liberation_(Schriftart) – http://scripts.sil.org/cms/scripts/page.php?item_id=OFL_web
        if (style == Font.NORMAL)     return new Font(this.load("fonts/Liberation/LiberationSans-Regular.ttf"),    size, Font.NORMAL, color);
        if (style == Font.BOLD)       return new Font(this.load("fonts/Liberation/LiberationSans-Bold.ttf"),       size, Font.NORMAL, color);
        if (style == Font.BOLDITALIC) return new Font(this.load("fonts/Liberation/LiberationSans-BoldItalic.ttf"), size, Font.NORMAL, color);
        if (style == Font.ITALIC)     return new Font(this.load("fonts/Liberation/LiberationSans-Italic.ttf"),     size, Font.NORMAL, color);
        return new Font(this.load("fonts/Liberation/LiberationSans-Regular.ttf"), size, style, color);
    }

    private BaseFont load(String path) { ... }
}

XMLWorker使用以下代码将其连接:

HtmlPipelineContext html = new HtmlPipelineContext(null);
html.setTagFactory(Tags.getHtmlTagProcessorFactory());
CSSResolver css = XMLWorkerHelper.getInstance().getDefaultCssResolver(true);

// We need to control the FontProdiver!
html.setCssAppliers(new CssAppliersImpl(new PrintFontProvider()));

Pipeline<?> pipeline = new CssResolverPipeline(css, new HtmlPipeline(html, new PdfWriterPipeline(this.document, writer)));
XMLWorker worker = new XMLWorker(pipeline, true);
XMLParser p = new XMLParser(worker);
p.parse(new ByteArrayInputStream(StringUtils.iTextHTML(string).getBytes()));

最简单的HTML元素以这种方式工作......但也有一些这似乎忽略了FontProvider并继续使用 Helvetica字体 ,不会被嵌入到PDF
/ A(我们没有该字体)。例如<ol><li>...</li></ol>利用这个。

Caused by: com.itextpdf.text.pdf.PdfXConformanceException: All the fonts must be embedded. This one isn't: Helvetica
at com.itextpdf.text.pdf.internal.PdfXConformanceImp.checkPDFXConformance(PdfXConformanceImp.java:225)
at com.itextpdf.text.pdf.PdfWriter.addSimple(PdfWriter.java:2192)
at com.itextpdf.text.pdf.PdfContentByte.setFontAndSize(PdfContentByte.java:1444)
at com.itextpdf.text.pdf.PdfDocument.writeLineToContent(PdfDocument.java:1463)
at com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:968)
at com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:841)
at com.itextpdf.text.pdf.ColumnText.showTextAligned(ColumnText.java:1189)
at com.itextpdf.text.pdf.ColumnText.showTextAligned(ColumnText.java:1208)
at com.itextpdf.text.pdf.PdfDocument.flushLines(PdfDocument.java:1193)
at com.itextpdf.text.pdf.PdfDocument.newPage(PdfDocument.java:830)
at com.itextpdf.text.Document.newPage(Document.java:367)

我已经没有办法立即解决Helvetica的问题了……尝试解决这个问题8个小时以上……还有其他想法吗?


问题答案:

我已经挖得更深一些,并专程从OrderedUnorderedList过度ListItemList

/**
 * Adds an <CODE>Element</CODE> to the <CODE>List</CODE>.
 *
 * @param   o       the element to add.
 * @return true if adding the object succeeded
 * @since 5.0.1 (signature changed to use Element)
 */
@Override
public boolean add(final Element o) {
    if (o instanceof ListItem) {
        ListItem item = (ListItem) o;
        if (this.numbered || this.lettered) {
            Chunk chunk = new Chunk(this.preSymbol, this.symbol.getFont());
            chunk.setAttributes(this.symbol.getAttributes());
            int index = this.first + this.list.size();
            if ( this.lettered )
                chunk.append(RomanAlphabetFactory.getString(index, this.lowercase));
            else
                chunk.append(String.valueOf(index));
            chunk.append(this.postSymbol);
            item.setListSymbol(chunk);
        }
        else {
            item.setListSymbol(this.symbol);
        }
        item.setIndentationLeft(this.symbolIndent, this.autoindent);
        item.setIndentationRight(0);
        return this.list.add(item);
    }
    else if (o instanceof List) {
        List nested = (List) o;
        nested.setIndentationLeft(nested.getIndentationLeft() + this.symbolIndent);
        this.first--;
        return this.list.add(nested);
    }
    return false;
}

这段代码指的this.symbol.getFont()是在类初始化时将其设置为undefined …

public class List implements TextElementArray, Indentable {

    [...]

    /** This is the listsymbol of a list that is not numbered. */
    protected Chunk symbol = new Chunk("- ");

我只是简单地使用了另一个Chunk构造函数,该构造函数具有Font我的想法,所以… …已 解决 。编号列表不再使用
Helvetica, 而是正确嵌入了我自己的字体。

这花了我很长时间!另一种方法可能是为其实现自己的TagProcessor,<ol>但是我们没有时间了。我将为此提交一个错误报告…我们将看看它是否更灵活地解决了。



 类似资料:
  • 问题内容: 到目前为止,给我带来了很多麻烦,所以我想摆脱它。尽管spring框架文档清楚地说明了应该做的事情,但实际上 并没有摘要列表。 所以我一直坚持删除并得到错误 -在名称为的中找不到带有请求的映射 对于所有应该由控制器类解决的Url(在这种情况下:)。有什么建议可以让我了解更多信息吗?我非常想知道到底由代表什么标签。 问题答案: 你可以用来自定义定义的每个bean 。现在,javadocs详

  • 问题内容: 到现在为止,给我造成了很多麻烦,所以我想摆脱它。尽管spring框架文档清楚地说明了应该做的事情,但实际上 并没有摘要列表。 所以我坚持删除并现在得到错误 WARN osweb.servlet.PageNotFound-在DispatcherServlet中,名称为’workoutsensor’的URI [/ webapp / trainees]的HTTP请求未找到映射 对于所有应该由

  • 我正在使用Spring启动版本2.1.5。发布,我试图删除log4j 1.2.17 jar尝试排除logic.insideSpring启动启动器依赖它不起作用。你能帮我解决log4j问题吗。我尝试升级Spring Boot版本,但我在maven依赖项下的eclipse中看到依赖项...提前谢谢。

  • 我有JavaWebService代码在我的eclipse。我使用了@WebService@Webmethod,@XmlElements,@XmlType,@XmlAccessorType 现在我正在使用cxf框架中的java2ws命令生成wsdl。这是命令 我的wsdl文件包含agr0作为我不想要的名称,因为当我将其导入SoapUI时。它正在字段周围添加标记。 下面是带有arg0的wsdl部分 下

  • 问题内容: 我正在使用Apache Derby嵌入式数据库在Maven项目中进行单元测试。不幸的是,每当运行测试时,我最终都会在项目根目录中找到该文件。数据库本身是在目录()中创建的,因此这不是问题。在查阅参考指南之后, 我尝试在JDBC url()上设置参数,但这似乎是针对其他日志的,因此仍然会出现。 任何帮助深表感谢。 问题答案: 您可以通过创建以下类来摆脱文件 并设置JVM系统属性,例如,使

  • 在这段代码中,我从\u RETURN\u VALUE得到了\u SOME\u PATH\u上的