Mr.*_*. P 3 java apache-fop web
使用 Apache FOP 创建 PDF 时,可以使用配置文件嵌入字体。当应用程序是 Web 应用程序并且需要在 WAR 文件中嵌入字体(因此被视为资源)时,就会出现问题。
使用特定容器的文件夹结构来确定 war 的确切位置是不可接受的(当我们在配置 xml 文件中将 tag 设置为 时./,它被设置为运行容器的基本文件夹,如C:\Tomcat\bin)。
所以问题是:有人知道以编程方式嵌入字体的方法吗?
在经历了大量 FOP java 代码之后,我设法让它工作。
主要思想是强制 FOP 使用自定义PDFRendererConfigurator,在getCustomFontCollection()执行时将返回所需的字体列表。
为了做到这一点,我们需要创建PDFDocumentHandlerMaker将返回自定义PDFDocumentHandler(表单方法makeIFDocumentHandler())的自定义,然后返回我们的自定义PDFRendererConfigurator(来自getConfigurator()方法),如上所述,它将列出自定义字体列表。
然后,只需定制添加PDFDocumentHandlerMaker到RendererFactory,它会工作。
FopFactory > RendererFactory > PDFDocumentHandlerMaker > PDFDocumentHandler > PDFRendererConfigurator
FopTest.java
public class FopTest {
public static void main(String[] args) throws Exception {
// the XSL FO file
StreamSource xsltFile = new StreamSource(
Thread.currentThread().getContextClassLoader().getResourceAsStream("template.xsl"));
// the XML file which provides the input
StreamSource xmlSource = new StreamSource(
Thread.currentThread().getContextClassLoader().getResourceAsStream("employees.xml"));
// create an instance of fop factory
FopFactory fopFactory = new FopFactoryBuilder(new File(".").toURI()).build();
RendererFactory rendererFactory = fopFactory.getRendererFactory();
rendererFactory.addDocumentHandlerMaker(new CustomPDFDocumentHandlerMaker());
// a user agent is needed for transformation
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
// Setup output
OutputStream out;
out = new java.io.FileOutputStream("employee.pdf");
try {
// Construct fop with desired output format
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);
// Setup XSLT
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(xsltFile);
// Resulting SAX events (the generated FO) must be piped through to
// FOP
Result res = new SAXResult(fop.getDefaultHandler());
// Start XSLT transformation and FOP processing
// That's where the XML is first transformed to XSL-FO and then
// PDF is created
transformer.transform(xmlSource, res);
} finally {
out.close();
}
}
}
Run Code Online (Sandbox Code Playgroud)
自定义PDFDocumentHandlerMaker.java
public class CustomPDFDocumentHandlerMaker extends PDFDocumentHandlerMaker {
@Override
public IFDocumentHandler makeIFDocumentHandler(IFContext ifContext) {
CustomPDFDocumentHandler handler = new CustomPDFDocumentHandler(ifContext);
FOUserAgent ua = ifContext.getUserAgent();
if (ua.isAccessibilityEnabled()) {
ua.setStructureTreeEventHandler(handler.getStructureTreeEventHandler());
}
return handler;
}
}
Run Code Online (Sandbox Code Playgroud)
自定义PDFDocumentHandler.java
public class CustomPDFDocumentHandler extends PDFDocumentHandler {
public CustomPDFDocumentHandler(IFContext context) {
super(context);
}
@Override
public IFDocumentHandlerConfigurator getConfigurator() {
return new CustomPDFRendererConfigurator(getUserAgent(), new PDFRendererConfigParser());
}
}
Run Code Online (Sandbox Code Playgroud)
CustomPDFRendererConfigurator.java
public class CustomPDFRendererConfigurator extends PDFRendererConfigurator {
public CustomPDFRendererConfigurator(FOUserAgent userAgent, RendererConfigParser rendererConfigParser) {
super(userAgent, rendererConfigParser);
}
@Override
protected FontCollection getCustomFontCollection(InternalResourceResolver resolver, String mimeType)
throws FOPException {
List<EmbedFontInfo> fontList = new ArrayList<EmbedFontInfo>();
try {
FontUris fontUris = new FontUris(Thread.currentThread().getContextClassLoader().getResource("UbuntuMono-Bold.ttf").toURI(), null);
List<FontTriplet> triplets = new ArrayList<FontTriplet>();
triplets.add(new FontTriplet("UbuntuMono", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL));
EmbedFontInfo fontInfo = new EmbedFontInfo(fontUris, false, false, triplets, null, EncodingMode.AUTO, EmbeddingMode.AUTO);
fontList.add(fontInfo);
} catch (Exception e) {
e.printStackTrace();
}
return createCollectionFromFontList(resolver, fontList);
}
}
Run Code Online (Sandbox Code Playgroud)