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

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

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

    Java軟件報(bào)表軟件技術(shù)博客

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

    Java開發(fā)的報(bào)表工具FineReport中,假如在目錄下保存了幾個(gè)XML文件,希望把XML文件轉(zhuǎn)換為報(bào)表數(shù)據(jù)源,同時(shí)希望展示動(dòng)態(tài)xml數(shù)據(jù)源的效果,這時(shí)可通過參數(shù)的方式,動(dòng)態(tài)獲取xml字段中的值再作為報(bào)表數(shù)據(jù)源。

    Northwind.xml記錄數(shù)據(jù)格式如下:


    <?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>

    最終用于制作報(bào)表的數(shù)據(jù)源形式如下:


    對(duì)于這樣的情況我們?nèi)绾蝸韺?shí)現(xiàn)呢?FineReport中可以通過自定義程序數(shù)據(jù)集來對(duì)xml字段數(shù)據(jù)進(jìn)行解析,最終返回所希望的數(shù)據(jù)表。實(shí)現(xiàn)步驟如下:

    1、 定義XMLColumnNameType4Demo封裝類

    首先定義參數(shù)nametype,供其他類直接調(diào)用,安全性比較高,詳細(xì)代碼如下:


    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接口,實(shí)現(xiàn)getColumnCountgetColumnNamegetRowCountgetValueAt四個(gè)方法,詳細(xì)代碼如下:


    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是獲取數(shù)據(jù)的接口 
     *  
     * 這里通過init方法一次性取數(shù)后,構(gòu)造一個(gè)二維表對(duì)象來實(shí)現(xiàn)DataModel的各個(gè)取數(shù)方法 
     
    */  
    public class XMLParseDemoDataModel extends AbstractDataModel {  
        
    // 數(shù)據(jù)類型標(biāo)識(shí)  
        public static final int COLUMN_TYPE_STRING = 0;  
        
    public static final int COLUMN_TYPE_INTEGER = 1;  
        
    public static final int COLUMN_TYPE_BOOLEAN = 2;  
      
        
    // 緩存取出來的數(shù)據(jù)  
        protected List row_list = null;  
      
        
    // 數(shù)據(jù)對(duì)應(yīng)的節(jié)點(diǎn)路徑  
        private String[] xPath;  
        
    // 節(jié)點(diǎn)路徑下包含的需要取數(shù)的節(jié)點(diǎn)  
        private XMLColumnNameType4Demo[] columns;  
      
        
    private String filePath;  
      
        
    public XMLParseDemoDataModel(String filename, String[] xPath,  
                XMLColumnNameType4Demo[] columns) {  
            
    this.filePath = filename;  
            
    this.xPath = xPath;  
            
    this.columns = columns;  
        }  
      
        
    /** 
         * 取出列的數(shù)量 
         
    */  
        
    public int getColumnCount() throws TableDataException {  
            
    return columns.length;  
        }  
      
        
    /** 
         * 取出相應(yīng)的列的名稱 
         
    */  
        
    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;  
        }  
      
        
    /** 
         * 取出得到的結(jié)果集的總的行數(shù) 
         
    */  
        
    public int getRowCount() throws TableDataException {  
            
    this.init();  
            
    return row_list.size();  
        }  
      
        
    /** 
         * 取出相應(yīng)位置的值 
         
    */  
        
    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];  
        }  
      
        
    /** 
         * 釋放一些資源,取數(shù)結(jié)束后,調(diào)用此方法來釋放資源 
         
    */  
        
    public void release() throws Exception {  
            
    if (this.row_list != null) {  
                
    this.row_list.clear();  
                
    this.row_list = null;  
            }  
        }  
      
        
    /** ************************************************** */  
        
    /** ***********以上是實(shí)現(xiàn)DataModel的方法*************** */  
        
    /** ************************************************** */  
      
        
    /** ************************************************** */  
        
    /** ************以下為解析XML文件的方法**************** */  
        
    /** ************************************************** */  
      
        
    // 一次性將數(shù)據(jù)取出來  
        protected void init() throws TableDataException {  
            
    if (this.row_list != null)  
                
    return;  
      
            
    this.row_list = new ArrayList();  
            
    try {  
                
    // 使用SAX解析XML文件, 使用方法請(qǐng)參見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);  
            }  
        }  
      
        
    /** 
         * 基本原理就是解析器在遍歷文件時(shí) 發(fā)現(xiàn)節(jié)點(diǎn)開始標(biāo)記時(shí),調(diào)用startElement方法 讀取節(jié)點(diǎn)內(nèi)部?jī)?nèi)容時(shí),調(diào)用characters方法 
         * 發(fā)現(xiàn)節(jié)點(diǎn)結(jié)束標(biāo)記時(shí),調(diào)用endElement 
         
    */  
        
    private class DemoHandler extends DefaultHandler {  
            
    private List levelList = new ArrayList(); // 記錄當(dāng)前節(jié)點(diǎn)的路徑  
            private Object[] values; // 緩存一條記錄  
            private int recordIndex = -1// 當(dāng)前記錄所對(duì)應(yīng)的列的序號(hào),-1表示不需要記錄  
      
            
    public void startElement(String uri, String localName, String qName,  
                    Attributes attributes) 
    throws SAXException {  
                
    // 記錄下  
                levelList.add(qName);  
      
                
    if (isRecordWrapTag()) {  
                    
    // 開始一條新數(shù)據(jù)的記錄  
                    values = new Object[XMLParseDemoDataModel.this.columns.length];  
                } 
    else if (needReadRecord()) {  
                    
    // 看看其對(duì)應(yīng)的列序號(hào),下面的characters之后執(zhí)行時(shí),根據(jù)這個(gè)列序號(hào)來設(shè)置值存放的位置。  
                    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()) {  
                        
    // 一條記錄結(jié)束,就add進(jìn)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;  
            }  
      
            
    // 是否匹配設(shè)定的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;  
            }  
      
            
    // 獲取該字段的序號(hào)  
            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、定義程序數(shù)據(jù)集XMLDemoTableData

    通過參數(shù)filename,動(dòng)態(tài)顯示xml文件內(nèi)容,首先xml文件需要放到某個(gè)目錄下,如下代碼是放到D盤,并且定義需要解析的數(shù)據(jù)列,這邊定義的數(shù)據(jù)列名稱,根xml內(nèi)字段名稱是一一對(duì)用的。詳細(xì)代碼如下:

                   return;  
                }  
            }  
        }  
          
        
    private  void readCol0(XMLEventReader reader)  
                
    throws XMLStreamException {  
            
    while (reader.hasNext()) {  
                XMLEvent event 
    = reader.nextEvent();  
                
    if (event.isStartElement()) {  
                    
    //deep是控制層數(shù)的,只把xml中對(duì)應(yīng)的層的加入到列名中  
                    deep++;  
                    
    //表示已經(jīng)進(jìn)入到了列名那一層  
                    if(deep==COL_DEEP){  
                        flag
    =true;  
                    }  
                    
    //如果在高層,并且已經(jīng)進(jìn)入到了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()) {  
                    
    //對(duì)數(shù)據(jù)值不做處理  
                } 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 配置程序數(shù)據(jù)源

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


    6、使用程序數(shù)據(jù)源

    在模板數(shù)據(jù)集窗口,點(diǎn)擊預(yù)覽按鈕,彈出參數(shù)對(duì)話框,輸入要顯示的xml文件名稱,點(diǎn)擊確定則可以把Northwind.xml文件里面的數(shù)據(jù)讀取出來轉(zhuǎn)換報(bào)表數(shù)據(jù)源了,如下圖:




    主站蜘蛛池模板: 精品无码一区二区三区亚洲桃色| 啦啦啦完整版免费视频在线观看| 亚洲精品国产高清嫩草影院| 阿v免费在线观看| 免费人成视频在线观看不卡| 国产天堂亚洲国产碰碰| 国产免费私拍一区二区三区 | 国产精品亚洲小说专区| 国产jizzjizz免费视频| 国产成人亚洲精品蜜芽影院| 国产一区二区三区无码免费| 国产精品亚洲一区二区三区在线观看 | 亚洲第一AV网站| 久久精品电影免费动漫| 亚洲一区二区电影| 亚洲综合免费视频| 亚洲中字慕日产2021| 最近最好的中文字幕2019免费 | 久久精品无码专区免费| 亚洲精品成人片在线观看精品字幕| a毛片全部播放免费视频完整18| 亚洲欧洲国产精品香蕉网| 成全视频高清免费观看电视剧| 亚洲成人激情在线| 国产免费不卡视频| 亚洲最大的成人网| 国产伦精品一区二区三区免费迷| 特级毛片aaaa免费观看| 亚洲欧洲∨国产一区二区三区 | 亚洲国产亚洲片在线观看播放| 欧美在线看片A免费观看| 亚洲精品日韩一区二区小说| 又色又污又黄无遮挡的免费视 | 免费在线观看的黄色网址| www.xxxx.com日本免费| 亚洲AV无码乱码国产麻豆| 亚洲电影在线免费观看| 亚洲精品理论电影在线观看| 精品在线视频免费| 亚洲人成色99999在线观看| 亚洲人成人网毛片在线播放|