简体   繁体   English

如何使用xsl FO在pdf中打印数组

[英]How to print array in pdf using xsl FO

I have a collection of objects which i want to print to pdf in a templated format. 我有一个对象集合,我想以模板格式将其打印为pdf。 I have tried to print the collection as PDF using the code below, but i do not see any text rendered in PDF after file is created. 我尝试使用下面的代码将收藏集打印为PDF,但是创建文件后看不到PDF中呈现的任何文本。

The java code is as follows: Java代码如下:

FopFactory fopFactory = FopFactory.newInstance();
OutputStream out = new BufferedOutputStream(new FileOutputStream(new File("/home/myfile.pdf")));
try {
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out);
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(); 
    Eden[] ed=new Eden[3];
    for(int i=0;i<ed.length;i++)
    {
        ed[i]=new Eden();
    ed[i].setBlow(String.valueOf(i));
    }
Source src = new StreamSource(new File("/home/tables.fo"));
Result res = new SAXResult(fop.getDefaultHandler());
transformer.setParameter("dep", ed);
transformer.transform(src, res);
} finally {
out.close();
}

The fo file is as follows: fo文件如下:

<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" 
 xmlns:xsl="http://www.w3.org    /1999/XSL/Transform">
   <fo:layout-master-set>
    <fo:simple-page-master master-name="my-page">
  <fo:region-body margin="0.5in"/>
</fo:simple-page-master>
 </fo:layout-master-set>
  <fo:page-sequence master-reference="my-page">
 <fo:flow flow-name="xsl-region-body" font="7pt Times">
    <fo:block border="thin solid black" text-align="center">
    <xsl:for-each select="dep">
        {$blow}
    </xsl:for-each>
</fo:block>
 </fo:flow>
  </fo:page-sequence>
</fo:root>

There is no way to output values using XSL- F (ormatting) O (bjects). 无法使用XSL- F (格式化) O (对象)输出值。 The example you're using does not in fact do an XSLT transformation which is required to be able to pass values to your stylesheet. 您正在使用示例实际上并没有进行XSLT转换,这是将值传递到样式表所必需的。

The following code will do what you want, the only difference from your code being the XSLT transformation: 以下代码将执行您想要的操作,与您的代码唯一的不同是XSLT转换:

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.FileOutputStream;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;

import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.MimeConstants;


public class test {

    public static void main(String[] args) throws FOPException, TransformerException, IOException 
    {
    /*..*/

     // Step 1: Construct a FopFactory
     // (reuse if you plan to render multiple documents!)
     FopFactory fopFactory = FopFactory.newInstance();

     // Step 2: Set up output stream.
     // Note: Using BufferedOutputStream for performance reasons (helpful with FileOutputStreams).
     OutputStream out = new BufferedOutputStream(new FileOutputStream(new File("F:/myfile.pdf")));

     try 
     {
        // Step 3: Construct fop with desired output format
        Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out);

        // Step 5: Setup input and output for XSLT transformation
        // Setup input stream

        Source xsltSource = new StreamSource(new File("F:/myfile.xsl"));
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer(xsltSource);

        int[] array = {1,2,3};
        transformer.setParameter("test", "1234");
        transformer.setParameter("testRaw", array);

        // Resulting SAX events (the generated FO) must be piped through to FOP
        Result res = new SAXResult(fop.getDefaultHandler());

        transformer.transform(xsltSource, res);

     } 
     finally 
     {
         out.close();
     }
    }

}

Now, to use the parameter in your XSL stylesheet (myfile.xsl for me), it will have to look like the following: 现在,要在XSL样式表(对我来说是myfile.xsl)中使用参数,它必须看起来像以下内容:

<xsl:stylesheet version="2.0" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:param name="test"/>
    <xsl:param name="testRaw"/>
    <xsl:template match="/">
        <fo:root>
           <fo:layout-master-set>
            <fo:simple-page-master master-name="my-page">
          <fo:region-body margin="0.5in"/>
        </fo:simple-page-master>
         </fo:layout-master-set>
          <fo:page-sequence master-reference="my-page">
         <fo:flow flow-name="xsl-region-body" font="7pt Times">
            <fo:block border="thin solid black" text-align="center">
                <xsl:value-of select="$test"/>
            </fo:block>
            <fo:block break-before="page" border="thin solid black" text-align="center">
                <xsl:value-of select="$testRaw"/>
            </fo:block>
         </fo:flow>
          </fo:page-sequence>
        </fo:root>
    </xsl:template>
</xsl:stylesheet>

This stylesheet defines two parameters: "test" and "testRaw", which are both output to two separate pages. 该样式表定义了两个参数:“ test”和“ testRaw”,它们都输出到两个单独的页面。 To do this, you use <xsl:value-of select="$paramName"/> . 为此,请使用<xsl:value-of select="$paramName"/>

In the code I posted, the two values were a string and an array of int. 在我发布的代码中,两个值是一个字符串和一个int数组。 PLEASE NOTE: You will NOT be able to just pass any class to a stylesheet and expect the XSL transformer to know about it. 请注意:您将能够只是传递任何类的样式表,并期望XSL转换来了解它。 This will not work. 这是行不通的。 Usually, parameters passed to a stylesheet are considered string values. 通常,传递给样式表的参数被视为字符串值。 If you pass anything else, you need to make sure your stylesheet and transformer can actually handle it. 如果传递其他任何内容,则需要确保样式表和转换器可以实际处理它。

Run the code on your machine and have a look at what's written to the second page: It's just gibberish, since the stylesheet and transformer cannot process an array of int. 在您的计算机上运行代码,然后看看第二页上写的内容:这简直是胡言乱语,因为样式表和转换器无法处理int数组。 If you really need to process data from a custom class, I'd suggest passing the values you really need to the stylesheet as (concatenated) strings. 如果您确实需要处理来自自定义类的数据,建议将您真正需要的值作为(连接的)字符串传递给样式表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM