XML文件到RTF和PDF的转换



Author: Holyfair
E-Mail: [email protected]



一.    序

     在一些运用中,我们通常会把一些文本和配置信息转换成XML文件进行传输,修改,保存.特别是具有一定模板性质的文档用XML文件来实现其管理就显得相当的方便了.提供对于XML文件的操作的java API很多,诸于DOM,JDOM,Castor,SAX,XMLReader,XPath,XSLT等等. 具体的这些API的用法这里就不多提了. 当使用这些接口实现XML的操作后,对于有些文档而言最终必须呈现给用户看的还是我们通常所熟悉的WORD和PDF文档.我们这里就来看一下从一个XML文件到RTF和PDF文件转换的实现.



二.    从XML到PDF

    对于一个具有一定模板性质的XML文件,我们可以用FOP API来实现其到PDF的转换.

   FOP需要fop.jar. 我们可以到http://xml.apache.org/fop/ 上获取和了解其用法.

   以一个一般复杂的XML文件为例:

   要转换XML文档 test.xml 如下:
  


 
  objective here
  scope here
  responsibilities here
  reference here
  
   
      term here
   

   
       definition here
   

  

 

 
  
   summary here
   breakdown here
  

  
   
        content here.
   

  

  
   
      content2 here.
   

  

 featureInteractions here
 

 
  
   
    estring here
   

   
      resourceid here
   

   
     rqmt here.
   

  

  

     对于这样一个XML文档,我们要将其转化成PDF格式必须建立一个XSL-FO文件,来定义对各element和value格

式的转换.

     我们建立XSL-FO文件 test.xsl 如下:  
 



 
 
 
 
 
  
   
    
     
    

   

   
    
     Cardiac Feature SRS
         

     
      
     

    

   

  

 

 
 
 
 
  1.  Intruction
  1.1 Objective
  
   
  

  1.2 Scope
  
   
  

  1.3. Responsibilities
  
   
  

  1.4. References
  
   
  

  1.5. Definitions, Acronyms, and Abbreviations
  
   
    
    
    
     
      
       
        Term
       

      

      
       
        Definition
       

      

     

     
      
       
        
         
        

       

       
        
         
        

       

      

     

    

   

  

 

 
  2. General Description
  2.1. Feature Name
  2.1.1. Feature Summary
  
   
  

  2.1.2. Feature Breakdown
  
   
  

  2.2. Feature Requirements
  
   
    
   

  

  2.3. Feature Interactions
  
   
  

 

 
  3. String Resources
  
   
    
    
    
    
     
      
       
        English String
       

      

      
       
        Resource ID
       

      

      
       
        Rqmt
       

      

     

     
      
       
        
         
        

       

       
        
         
        

       

       
        
         
        

       

      

     

    

   

  

 



其具体的XSL-FO文件格式的语法可以参照一些其他资料.

建立好了此文件之后,我们就可以用FOP提供的一些接口方便的进行转换了.

FOP提供了XML->FO,XML->PDF,FO-PDF,OBJ->FO,OBJ->PDF的转换接口.

我们这里以XML->PDF的为例,其余的可以参照FOP包里相应的DEMO.

public class ExampleXML2PDF {

    public void convertXML2PDF(File xml, File xslt, File pdf)
                throws IOException, FOPException, TransformerException {
         Driver driver = new Driver();
        Logger logger = new ConsoleLogger(ConsoleLogger.LEVEL_INFO);
        driver.setLogger(logger);
        MessageHandler.setScreenLogger(logger);

        //Setup Renderer (output format)       
        driver.setRenderer(Driver.RENDER_PDF);
       
        //Setup output
        OutputStream out = new java.io.FileOutputStream(pdf);
        try {
            driver.setOutputStream(out);

            //Setup XSLT
            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer transformer = factory.newTransformer(new StreamSource(xslt));
       
            //Setup input for XSLT transformation
            Source src = new StreamSource(xml);
       
            //Resulting SAX events (the generated FO) must be piped through to FOP
            Result res = new SAXResult(driver.getContentHandler());

            //Start XSLT transformation and FOP processing
            transformer.transform(src, res);
        } finally {
            out.close();
        }
    }


    public static void main(String[] args) {
        try {
            System.out.println("FOP ExampleXML2PDF/n");
            System.out.println("Preparing...");

            //Setup directories
            File baseDir = new File(".");
            File outDir = new File(baseDir, "out");
            outDir.mkdirs();

            //Setup input and output files           
            File xmlfile = new File(baseDir, "test.xml");
            File xsltfile = new File(baseDir, "test.xsl");
            File pdffile = new File(outDir, "test.pdf");

            System.out.println("Input: XML (" + xmlfile + ")");
            System.out.println("Stylesheet: " + xsltfile);
            System.out.println("Output: PDF (" + pdffile + ")");
            System.out.println();
            System.out.println("Transforming...");
           
            ExampleXML2PDF app = new ExampleXML2PDF();
            app.convertXML2PDF(xmlfile, xsltfile, pdffile);
           
            System.out.println("Success!");
        } catch (Exception e) {
            System.err.println(ExceptionUtil.printStackTrace(e));
            System.exit(-1);
        }
    }
}


       这样我们就很轻易地实现了XML文档到PDF文档的转换.

     如果这些用在webservice的servlet中,想从xml文件直接生成pdf传输给浏览者而并不生成的pdf文件,我们可以如

下实现:

public class FOPServlet extends HttpServlet {
    public static final String FO_REQUEST_PARAM = "fo";
    public static final String XML_REQUEST_PARAM = "xml";
    public static final String XSL_REQUEST_PARAM = "xsl";

    public void doGet(HttpServletRequest request,
                      HttpServletResponse response) throws ServletException {
        try {
            String xmlParam =getServletContext().getRealPath("WEB-INF/doc/xml/test.xml");
            String xslParam =getServletContext().getRealPath("WEB-INF/doc/xsl/test.xsl");

            if ((xmlParam != null) && (xslParam != null)) {
                XSLTInputHandler input =
                  new XSLTInputHandler(new File(xmlParam),
                                       new File(xslParam));
                renderXML(input, response);
            } else {
                PrintWriter out = response.getWriter();
                out.println("Error/n"+
                            "

FopServlet Error

No 'fo' "+
                            "request param given.");
            }
        } catch (ServletException ex) {
            throw ex;
        }
        catch (Exception ex) {
            throw new ServletException(ex);
        }
    }
    public void renderXML(XSLTInputHandler input,
                          HttpServletResponse response) throws ServletException {
        try {
            ByteArrayOutputStream out = new ByteArrayOutputStream();

            response.setContentType("application/pdf");

            Driver driver = new Driver();
            driver.setRenderer(Driver.RENDER_PDF);
            driver.setOutputStream(out);
            driver.render(input.getParser(), input.getInputSource());

            byte[] content = out.toByteArray();
            response.setContentLength(content.length);
            response.getOutputStream().write(content);
            response.getOutputStream().flush();
        } catch (Exception ex) {
            throw new ServletException(ex);
        }
    }

}





三.    XML to RTF

    xml到rtf的转换稍微有一些麻烦,我们没有直接从XML到RTF的API, 我们将要用的JFor API还没有整合到FOP

中去. JFor API可以实现 从 FO文件到RTF文件的转换, 它也提供了consle接口.
 
   我们可以从 www.jfor.org 上获取jfor相关信息.

    我们从XML文件到RTF文件的转换可以分为两步:

         1.    用FOP将 xml  转换成 fo

         2.    用JFor将 fo 转换成RTF

    3.1    用FOP将 xml  转换成 fo
         
           这一步我们可以很轻易的沿用上面所述的方法,如下实现xml到fo 的转换,依然会用到上面所用的xml文件

和xsl-fo文件.

             OutputStream foOut = new FileOutputStream(fofile);
            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer transformer = factory.newTransformer(new StreamSource(
                    xsltfile));
            Source src = new StreamSource(xmlfile);
            Result res = new StreamResult(foOut);          
            transformer.transform(src, res);
            foOut.close();

      3.2 用JFor将 fo 转换成RTF

      仅以Serlvet需求的实现为例:

            InputStream foInput = new FileInputStream(fofile);
            InputSource inputSource = new InputSource(foInput);
           
            ByteArrayOutputStream out = new ByteArrayOutputStream();
           Writer output = new OutputStreamWriter(out);

            response.setContentType("application/msword");

            new Converter(inputSource,output,Converter.createConverterOption ());
            output.flush();

            byte[] content = out.toByteArray();
           
            System.out.println(out.toString());

            response.setContentLength(content.length);
            response.getOutputStream().write(content);
            response.getOutputStream().flush();
           
            foInput.close();
            output.close();
            out.close();


这样我们就成功地将xml转化成了RTF格式的文件.

本文仅简述了大体的实现过程,具体的细节可参照各技术点的详细自述.

你可能感兴趣的:(XML,Technology)