当前位置: 首页 > 知识库问答 >
问题:

fop将多页中的一页呈现为pdf

潘自强
2023-03-14

我有一个针对xml内容和xsl标记运行apache fop的代码,并为我提供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(FPSIFSeriezer())。

我有几页报告,但我不需要处理所有的报告。是否有任何方法可以跳过某些页面或从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连接文件的示例,所以我想知道拆分多页文件的最佳方法是什么?

谢谢你!

共有1个答案

赵景曜
2023-03-14

我这样做的方式是使用自定义文档处理程序。

/**
 * 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;

你将在输出流中得到你需要的唯一页面。类空画家是一个肮脏的黑客。它是apache IFPainter的空实现,它在这里用于跳过页面内容并避免NPE。我对此不高兴,但这是我唯一能让它工作的方法。

请注意,我使用的是 FOP 1.1,如果您遇到此类问题,值得查看 trunk - 其中一些已经在那里解决了。我想在后备箱中不需要使用EmptyPainter进行肮脏的黑客攻击。

如果这里可以做得更好,请提供提示。

谢谢。

 类似资料:
  • 我要求在JSF2.2页面上输入2个输入值。我们正在使用Primefaces控件。然后通过h:command按钮将这些值提交给托管bean方法。 然后,基于这些值,我想将同一JSF页面上的一个单独的输出字段设置为一个特定的值。 因此,我目前的问题是尝试连接一个托管bean,以便它将一个值返回到我的JSF页面上的字段,在本例中,字段名是mgrs。主要的问题是,我要处理的是生成返回值的第三方库,我不确定

  • 使用Apache FOP在pdf中绘制页面边框最简单的方法是什么? 我可以通过将

  • 我正在使用Apache FOP XSL文件格式生成PDF。 我的要求是 PDF格式的表格数据 表大小很大,因此同一表扩展到多页(宽度方向,第一页中的列很少,其他列在下一页上) 第1页有3列(C1、C2、C3) 第2页有5列(C4、C5、C6、C7、C8) 少数单元格可能包含多行数据 问题描述: 当 Page-2 具有第 4 行、第 4 列的多行数据时,其行高会根据内容增加 但是在第 1 页中,第

  • 我的分页有点问题。我有两个包含数据库数据的表,我用laravel Paginator对其进行了分页。 现在我的问题是,当你进入,例如,第2页,它添加了什么?page=2,但这使得第一个表也转到第2页。 有没有办法得到这样的东西?

  • 我正在使用PhantomJS进行网页截图。 我看到过其他关于@font-face问题的帖子,但我页面上的字体呈现正确。我唯一的问题是,每次截图时,字体显示与前一个截图略有不同。所以尽管他们的渲染是正确的,但他们在截图上的外观是不一致的。 我已经尝试了许多修复,大多数都是基于这样的假设,即这与页面准备好之前拍摄的截图有关,但这似乎不是问题所在。例如,我已经延迟了截图,以便字体有时间加载和呈现,但这并

  • 我有一个pdf,里面总共有6页的图片。我想将第1页和第2页合并为单个pdf,以此类推,共3到6页。 我将所有6页的pdf拆分为单独的pdf。 从PyPDF2导入操作系统导入PdfFileReader、PdfFileWriter pdf_splitter: fname=os.path.splitext(os.path.basename(path))[0] if name=='main': path=