我有一个代码,它运行apache fop对xml内容和xsl标记,并给我apache中间格式输出:
StreamSource contentSource = new StreamSource(xmlContentStream);
StreamSource transformSource = new StreamSource(xslMarkupStream);
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
Transformer xslfoTransformer = getTransformer(transformSource);
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
IFDocumentHandler targetHandler = foUserAgent.getRendererFactory().createDocumentHandler(
foUserAgent, MimeConstants.MIME_PDF);
FPSIFSerializer fpsSerializer = new FPSIFSerializer();
fpsSerializer.setContext(new IFContext(foUserAgent));
fpsSerializer.mimicDocumentHandler(targetHandler);
foUserAgent.setDocumentHandlerOverride(fpsSerializer);
Fop fop = fopFactory.newFop("application/X-fop-intermediate-format", foUserAgent, outStream);
DefaultHandler defaultHandler = fop.getDefaultHandler();
Result res = new SAXResult(defaultHandler);
xslfoTransformer.transform(contentSource, res);
然后我使用该中间格式文件来渲染pdf和png文件。 我可以在这里设置我自己的serilaizer(FPSIFSerializer())。
我有几页报告,但我不需要处理所有这些报告。有没有办法跳过一些页面或从IntermediateFormat中提取它们,所以我将能够例如仅将第一页渲染为png,然后将第二页渲染为pdf等? 那里 http://svn.apache.org/viewvc/xmlgraphics/fop/branches/archive/fop-1_1/examples/embedding/java/embedding/intermediate/ExampleConcat.java?view=markup 是一个如何通过IFConcatenator连接文件的例子,所以我想知道拆分多页文件的最佳方法?
Thank_you!
答案 0 :(得分:0)
我完成它的方式是使用自定义文档处理程序。
/**
* Custom Apache FOP Intermediate Format document handler which allows page skipping.
* Not thread safe.
*/
public class IFPageFilter extends IFDocumentHandlerProxy {
private static final Logger LOGGER = LoggerFactory.getLogger(IFPageFilter.class);
private int currentPage;
private final int desiredPage;
/**
* @param delegate The real document handler
* @param desiredPage the page you want to render (1-based). Other pages will be skipped.
*/
public IFPageFilter(final IFDocumentHandler delegate, final int desiredPage) {
super(delegate);
this.desiredPage = desiredPage;
}
@Override
public void startPage(final int index, final String name, final String pageMasterName, final Dimension size) throws IFException {
currentPage = index + 1;
if (currentPage == desiredPage) {
super.startPage(index, name, pageMasterName, size);
} else {
// do nothing
LOGGER.debug("Page skipped");
}
}
@Override
public IFPainter startPageContent() throws IFException {
if (currentPage == desiredPage) {
return super.startPageContent();
} else {
return EmptyPainter.getInstance();
}
}
@Override
public void endPageContent() throws IFException {
if (currentPage == desiredPage) {
super.endPageContent();
}
}
}
然后你可以像这样附上你的处理程序:
final IFDocumentHandler targetHandler = FOP_FACTORY.getRendererFactory().createDocumentHandler(userAgent, mime);
final IFPageFilter documentHandler = new IFPageFilter(targetHandler, page);
final ByteArrayOutputStream mimeOut = new ByteArrayOutputStream(XSL_STREAM_BUFFER_SIZE);
IFUtil.setupFonts(documentHandler);
// Tell the target handler where to write the PDF to
targetHandler.setResult(new StreamResult(mimeOut));
try (final InputStream is = ifStream.toInputStream()) {
final Source src = new StreamSource(is);
new IFParser().parse(src, documentHandler, userAgent);
}
return mimeOut;
您将获得输出流中唯一需要的页面。 类EmptyPainter是一个肮脏的黑客。它是apache IFPainter的空实现,它用于跳过页面内容并避免NPE。我对此并不满意,但这是我能够使其发挥作用的唯一方式。
请注意我使用的是FOP 1.1,如果你遇到这样的问题,那么值得看看后备箱 - 其中一些已经解决了。我想在主干中没有必要使用EmptyPainter进行肮脏的黑客攻击。
如果可以在这里做得更好,请提供建议。
由于