<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Java軟件報表軟件技術博客

    java報表軟件技術匯總 java報表軟件制作 報表軟件新聞
    posts - 355, comments - 100, trackbacks - 0, articles - 3
       :: 首頁 :: 新隨筆 ::  :: 聚合  :: 管理

    Java開發的報表工具FineReport中,假如在目錄下保存了幾個XML文件,希望把XML文件轉換為報表數據源,同時希望展示動態xml數據源的效果,這時可通過參數的方式,動態獲取xml字段中的值再作為報表數據源。

    Northwind.xml記錄數據格式如下:


    <?xml version="1.0" encoding="UTF-8"?>
    <Northwind>
        
    <Customers>
            
    <CustomerID>ALFKI</CustomerID>
            
    <CompanyName>ALfreds Futterkiste</CompanyName>
            
    <ContactName>Maria Anders</ContactName>
            
    <ContactTitle>Sales Representative</ContactTitle>
            
    <Address>Obere Str.57</Address>
            
    <City>Berlin</City>
            
    <PostalCode>12209</PostalCode>
            
    <Country>Germany</Country>
            
    <Phone>030-0074321</Phone>
            
    <Fax>030-0076545</Fax>
        
    </Customers>
    </Northwind>

    最終用于制作報表的數據源形式如下:


    對于這樣的情況我們如何來實現呢?FineReport中可以通過自定義程序數據集來對xml字段數據進行解析,最終返回所希望的數據表。實現步驟如下:

    1、 定義XMLColumnNameType4Demo封裝類

    首先定義參數nametype,供其他類直接調用,安全性比較高,詳細代碼如下:


    package com.fr.data;  
      
    public class XMLColumnNameType4Demo {  
        
    private int type = -1;  
        
    private String name = null;   
        
    public XMLColumnNameType4Demo(String name, int type) {  
            
    this.name = name;  
            
    this.type = type;  
        }  
        
    public String getName() {  
            
    return name;  
        }  
        
    public void setName(String name) {  
            
    this.name = name;  
        }      
        
    public int getType() {  
            
    return type;  
        }  
        
    public void setType(int type) {  
            
    this.type = type;  
        }  
    }

     

    2、定義XMLParseDemoDataModel.java類文件

    定義XMLParseDemoDataModel.java類繼承AbstractDataModel接口,實現getColumnCountgetColumnNamegetRowCountgetValueAt四個方法,詳細代碼如下:


    package com.fr.data;  
      
    import java.io.File;  
    import java.util.ArrayList;  
    import java.util.List;  
    import javax.xml.parsers.SAXParser;  
    import javax.xml.parsers.SAXParserFactory;  
    import org.xml.sax.Attributes;  
    import org.xml.sax.SAXException;  
    import org.xml.sax.helpers.DefaultHandler;  
    import com.fr.base.FRContext; 
    import com.fr.data.AbstractDataModel;  
    import com.fr.general.ComparatorUtils;
    import com.fr.general.data.TableDataException;
      
    /** 
     * XMLParseDemoDataModel 
     *  
     * DataModel是獲取數據的接口 
     *  
     * 這里通過init方法一次性取數后,構造一個二維表對象來實現DataModel的各個取數方法 
     
    */  
    public class XMLParseDemoDataModel extends AbstractDataModel {  
        
    // 數據類型標識  
        public static final int COLUMN_TYPE_STRING = 0;  
        
    public static final int COLUMN_TYPE_INTEGER = 1;  
        
    public static final int COLUMN_TYPE_BOOLEAN = 2;  
      
        
    // 緩存取出來的數據  
        protected List row_list = null;  
      
        
    // 數據對應的節點路徑  
        private String[] xPath;  
        
    // 節點路徑下包含的需要取數的節點  
        private XMLColumnNameType4Demo[] columns;  
      
        
    private String filePath;  
      
        
    public XMLParseDemoDataModel(String filename, String[] xPath,  
                XMLColumnNameType4Demo[] columns) {  
            
    this.filePath = filename;  
            
    this.xPath = xPath;  
            
    this.columns = columns;  
        }  
      
        
    /** 
         * 取出列的數量 
         
    */  
        
    public int getColumnCount() throws TableDataException {  
            
    return columns.length;  
        }  
      
        
    /** 
         * 取出相應的列的名稱 
         
    */  
        
    public String getColumnName(int columnIndex) throws TableDataException {  
            
    if (columnIndex < 0 || columnIndex >= columns.length)  
                
    return null;  
            String columnName 
    = columns[columnIndex] == null ? null  
                    : columns[columnIndex].getName();  
      
            
    return columnName;  
        }  
      
        
    /** 
         * 取出得到的結果集的總的行數 
         
    */  
        
    public int getRowCount() throws TableDataException {  
            
    this.init();  
            
    return row_list.size();  
        }  
      
        
    /** 
         * 取出相應位置的值 
         
    */  
        
    public Object getValueAt(int rowIndex, int columnIndex)  
                
    throws TableDataException {  
            
    this.init();  
            
    if (rowIndex < 0 || rowIndex >= row_list.size() || columnIndex < 0  
                    
    || columnIndex >= columns.length)  
                
    return null;  
            
    return ((Object[]) row_list.get(rowIndex))[columnIndex];  
        }  
      
        
    /** 
         * 釋放一些資源,取數結束后,調用此方法來釋放資源 
         
    */  
        
    public void release() throws Exception {  
            
    if (this.row_list != null) {  
                
    this.row_list.clear();  
                
    this.row_list = null;  
            }  
        }  
      
        
    /** ************************************************** */  
        
    /** ***********以上是實現DataModel的方法*************** */  
        
    /** ************************************************** */  
      
        
    /** ************************************************** */  
        
    /** ************以下為解析XML文件的方法**************** */  
        
    /** ************************************************** */  
      
        
    // 一次性將數據取出來  
        protected void init() throws TableDataException {  
            
    if (this.row_list != null)  
                
    return;  
      
            
    this.row_list = new ArrayList();  
            
    try {  
                
    // 使用SAX解析XML文件, 使用方法請參見JAVA SAX解析  
                SAXParserFactory f = SAXParserFactory.newInstance();  
                SAXParser parser 
    = f.newSAXParser();  
      
                parser.parse(
    new File(XMLParseDemoDataModel.this.filePath),  
                        
    new DemoHandler());  
            } 
    catch (Exception e) {  
                e.printStackTrace();  
                FRContext.getLogger().error(e.getMessage(), e);  
            }  
        }  
      
        
    /** 
         * 基本原理就是解析器在遍歷文件時 發現節點開始標記時,調用startElement方法 讀取節點內部內容時,調用characters方法 
         * 發現節點結束標記時,調用endElement 
         
    */  
        
    private class DemoHandler extends DefaultHandler {  
            
    private List levelList = new ArrayList(); // 記錄當前節點的路徑  
            private Object[] values; // 緩存一條記錄  
            private int recordIndex = -1// 當前記錄所對應的列的序號,-1表示不需要記錄  
      
            
    public void startElement(String uri, String localName, String qName,  
                    Attributes attributes) 
    throws SAXException {  
                
    // 記錄下  
                levelList.add(qName);  
      
                
    if (isRecordWrapTag()) {  
                    
    // 開始一條新數據的記錄  
                    values = new Object[XMLParseDemoDataModel.this.columns.length];  
                } 
    else if (needReadRecord()) {  
                    
    // 看看其對應的列序號,下面的characters之后執行時,根據這個列序號來設置值存放的位置。  
                    recordIndex = getColumnIndex(qName);  
                }  
            }  
      
            
    public void characters(char[] ch, int start, int length)  
                    
    throws SAXException {  
                
    if (recordIndex > -1) {  
                    
    // 讀取值  
                    String text = new String(ch, start, length);  
                    XMLColumnNameType4Demo type 
    = XMLParseDemoDataModel.this.columns[recordIndex];  
                    Object value 
    = null;  
                    
    if (type.getType() == COLUMN_TYPE_STRING) {  
                        value 
    = text;  
                    }  
                    
    if (type.getType() == COLUMN_TYPE_INTEGER) {  
                        value 
    = new Integer(text);  
                    } 
    else if (type.getType() == COLUMN_TYPE_BOOLEAN) {  
                        value 
    = new Boolean(text);  
                    }  
      
                    values[recordIndex] 
    = value;  
                }  
            }  
      
            
    public void endElement(String uri, String localName, String qName)  
                    
    throws SAXException {  
                
    try {  
                    
    if (isRecordWrapTag()) {  
                        
    // 一條記錄結束,就add進list中  
                        XMLParseDemoDataModel.this.row_list.add(values);  
                        values 
    = null;  
                    } 
    else if (needReadRecord()) {  
                        recordIndex 
    = -1;  
                    }  
                } 
    finally {  
                    levelList.remove(levelList.size() 
    - 1);  
                }  
            }  
      
            
    // 正好匹配路徑,確定是記錄外部的Tag  
            private boolean isRecordWrapTag() {  
                
    if (levelList.size() == XMLParseDemoDataModel.this.xPath.length  
                        
    && compareXPath()) {  
                    
    return true;  
                }  
      
                
    return false;  
            }  
      
            
    // 需要記錄一條記錄  
            private boolean needReadRecord() {  
                
    if (levelList.size() == (XMLParseDemoDataModel.this.xPath.length + 1)  
                        
    && compareXPath()) {  
                    
    return true;  
                }  
      
                
    return false;  
            }  
      
            
    // 是否匹配設定的XPath路徑  
            private boolean compareXPath() {  
                String[] xPath 
    = XMLParseDemoDataModel.this.xPath;  
                
    for (int i = 0; i < xPath.length; i++) {  
                    
    if (!ComparatorUtils.equals(xPath[i], levelList.get(i))) {  
                        
    return false;  
                    }  
                }  
      
                
    return true;  
            }  
      
            
    // 獲取該字段的序號  
            private int getColumnIndex(String columnName) {  
                XMLColumnNameType4Demo[] nts 
    = XMLParseDemoDataModel.this.columns;  
                
    for (int i = 0; i < nts.length; i++) {  
                    
    if (ComparatorUtils.equals(nts[i].getName(), columnName)) {  
                        
    return i;  
                    }  
                }  
      
                
    return -1;  
            }  
        }  
    }

    3、定義程序數據集XMLDemoTableData

    通過參數filename,動態顯示xml文件內容,首先xml文件需要放到某個目錄下,如下代碼是放到D盤,并且定義需要解析的數據列,這邊定義的數據列名稱,根xml內字段名稱是一一對用的。詳細代碼如下:

                   return;  
                }  
            }  
        }  
          
        
    private  void readCol0(XMLEventReader reader)  
                
    throws XMLStreamException {  
            
    while (reader.hasNext()) {  
                XMLEvent event 
    = reader.nextEvent();  
                
    if (event.isStartElement()) {  
                    
    //deep是控制層數的,只把xml中對應的層的加入到列名中  
                    deep++;  
                    
    //表示已經進入到了列名那一層  
                    if(deep==COL_DEEP){  
                        flag
    =true;  
                    }  
                    
    //如果在高層,并且已經進入到了col層,則退出  
                    if(deep<COL_DEEP&&flag){  
                        
    return;  
                    }  
                    
    if(deep!=COL_DEEP){  
                        
    continue;  
                    }  
                    System.out.println(
    "name: " + event.asStartElement().getName());  
                    readCol0(reader);  
                } 
    else if (event.isCharacters()) {  
                    
    //對數據值不做處理  
                } else if (event.isEndElement()) {  
                    deep
    --;  
                    
    return;  
                }  
            }  
        }  
        
    public static void main(String[] args){  
            XMLInputFactory inputFactory 
    = XMLInputFactory.newInstance();  
    //      in = new FileReader(new File(filePath));  
    //      XMLEventReader reader = inputFactory.createXMLEventReader(in);  
    //      readCol(reader,list);  
            BufferedInputStream in;  
            
    try {  
                in 
    = new BufferedInputStream(new FileInputStream(new File("D:/tmp/f.xml")));  
                
    byte[] ba=new byte[3];  
                in.read(ba,
    0,3);  
    //      System.out.println(in)  
            XMLEventReader reader = inputFactory.createXMLEventReader(in);  
            
    new XMLDemoTableData().readCol0(reader);  
            } 
    catch (Exception e) {  
                    
    // TODO Auto-generated catch block  
                    e.printStackTrace();  
                }  
        }  
    }

     

    5 配置程序數據源

    新建報表,模板數據集>程序數據集,選擇我們定義好的程序數據集XMLDemoTableData.class文件,名字可以自定義,如程序1


    6、使用程序數據源

    在模板數據集窗口,點擊預覽按鈕,彈出參數對話框,輸入要顯示的xml文件名稱,點擊確定則可以把Northwind.xml文件里面的數據讀取出來轉換報表數據源了,如下圖:




    主站蜘蛛池模板: 国产特级淫片免费看| 亚洲最大免费视频网| 在线涩涩免费观看国产精品| 久章草在线精品视频免费观看| 2019中文字幕免费电影在线播放| 岛国av无码免费无禁网站| 免费成人午夜视频| 国产亚洲精品精华液| 亚洲国产成人精品无码一区二区| 亚洲大尺度无码无码专线一区| 一级毛片一级毛片免费毛片| 久久综合九色综合97免费下载| 亚洲性线免费观看视频成熟| 国产在线19禁免费观看| 国产亚洲精品观看91在线| 激情综合亚洲色婷婷五月| 黄色三级三级免费看| 久草福利资源网站免费| 岛国片在线免费观看| 国产综合亚洲专区在线| 亚洲第一区视频在线观看| WWW亚洲色大成网络.COM| 成人精品视频99在线观看免费| 日韩免费精品视频| 亚洲国产婷婷香蕉久久久久久| 亚洲视频在线观看网站| 特级毛片aaaa免费观看| 亚洲一区二区三区免费在线观看| 免费一级毛片在播放视频| 亚洲高清无在码在线电影不卡| 精品久久久久久亚洲综合网| 最近中文字幕免费完整| www.亚洲一区| 亚洲伊人久久大香线蕉影院| 人与动性xxxxx免费| 亚洲黄色免费网站| 国产亚洲色视频在线| 日韩亚洲产在线观看| 永久免费AV无码网站国产| 日本免费人成视频播放| 亚洲国产美国国产综合一区二区|