`

创建SAX解析处理器

    博客分类:
  • poi
阅读更多

package com.ejintai.epcis_agro.transmission.fileDeal.impl;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import com.ejintai.epcis_agro.anno.ExcelAnno;
import com.ejintai.epcis_agro.biz.validation.Validation;
import com.ejintai.epcis_agro.biz.validation.ValidationFactory;
import com.ejintai.epcis_agro.constant.AlertCause;
/**
 *  创建SAX解析处理器必须继承自
 *  org.xml.sax.helpers.DefaultHandler
 * 实现响应的方法。
 */ 
public class ExcelSheetSAXHandler extends DefaultHandler { 
 
 @Autowired
 protected @Value("${excelImport.maxRow}")
 int maxRow;
 
    private SharedStringsTable sst; 
    private String lastContents; 
    private boolean nextIsString; 
    public List<Object> result = new ArrayList<Object>();
    private Class<?> excelVOs;
    private String edrReason;
    private Map<Integer, String> autoRead;
    private Map<String, Validation> validationMap;
    private int sheetIndex;
   
    private Object vo;
    private int r=1;//行
   
    private int c=0;//例
   
    int rowNum = 1;
    int td;
    private boolean nextIsRows;  //是否新的一行
     
    public ExcelSheetSAXHandler(SharedStringsTable sst,Class<?> excelVOs,String edrReason,int sheetIndex) { 
        this.sst = sst; 
        this.excelVOs=excelVOs;
        this.edrReason=edrReason;
        this.sheetIndex=sheetIndex;
         autoRead = getMappingFromClass(excelVOs);
   validationMap = getValidationMappingFromClass(excelVOs);  
   try{
    vo = excelVOs.newInstance();
   }catch (Exception e) {
   // TODO: handle exception
  }
    } 
     
    public void startElement(String uri, String localName, String name, 
            Attributes attributes) throws SAXException{ 
        // c => cell 
        if(name.equals("c")) { 
           
           // System.out.print("单元格"+attributes.getValue("r") + " - "); 
         if(c<26){//26个字母
          td=Integer.parseInt(attributes.getValue("r").substring(1));        //这里还是有缺陷。当例数超过Z,就不能这样处理了。 
         }else if(c<702){//到ZZ那里          
          td=Integer.parseInt(attributes.getValue("r").substring(2));            
         }else{
          //太多例,不支持
          throw new SAXException("太多例,不支持" );
         }
         
            if(td==r){//表示它们是一行的数据
             c++;//计算例
             r=td;
             nextIsRows=false;
            }else{             
             rowNum++;
             c=0;
             nextIsRows=true;
             r=td;             
            }
            String cellType = attributes.getValue("t"); 
            if(cellType != null && cellType.equals("s")) { 
                nextIsString = true; 
            } else { 
                nextIsString = false; 
            } 
        } 
        // Clear contents cache 
        lastContents = ""; 
    } 
     
    public void endElement(String uri, String localName, String name) 
            throws SAXException { 
        // Process the last contents as required. 
        // Do now, as characters() may be called more than once 
        if(nextIsString) { 
            int idx = Integer.parseInt(lastContents); 
            lastContents = new XSSFRichTextString(sst.getEntryAt(idx)).toString(); 
        nextIsString = false; 
        } 
 
        // v => contents of a cell 
        // Output after we've seen the string contents 
        if(name.equals("v")) { 
           // System.out.println("数据"+lastContents);          
           
            if(r!=1){//行 第一行不处理
             
             if(nextIsRows){//新的一行
              if(r>2){
              result.add(vo);       
              }
              try{
                     vo = excelVOs.newInstance();
                    }catch (Exception e) {
                    // TODO: handle exception
                   }
              setVo();
             }else{
              setVo();
             }               
            }           
        } 
    } 
    /**
     * 设置每行数据
     */
    private void setVo() throws SAXException{
     String propName = autoRead.get(c);
     if (null != propName) {//例
        try{
   BeanUtils.setProperty(vo, propName, lastContents);
   }catch (Exception e) {
    // TODO: handle exception
   }
     }
    }
 
    public void characters(char[] ch, int start, int length) 
            throws SAXException { 
        lastContents += new String(ch, start, length); 
    } 
    /**
     * 接收文档结束的通知
     */
    public void endDocument(){
      result.add(vo);
     // System.out.println("接收文档结束"); 
    }
  
    public void startDocument(){
     //System.out.println("接收文档开始");
    }
    private Map<Integer, String> getMappingFromClass(Class<?> annoClass) {
  Map<Integer, String> mapping = new HashMap<Integer, String>();

  // 枚举每一列和字段的对应关系
  Field[] fields = annoClass.getDeclaredFields();
  for (Field field : fields) {
   boolean hasAnnotation = field.isAnnotationPresent(ExcelAnno.class);
   // 有注解的才从Excel读取
   if (hasAnnotation) {
    ExcelAnno anno = field.getAnnotation(ExcelAnno.class);
    int column = anno.column();
    String fieldName = field.getName();
    mapping.put(column, fieldName);
   }
  }
  return mapping;
 }

 private Map<String, Validation> getValidationMappingFromClass(
   Class<?> annoClass) {
  Map<String, Validation> mapping = new HashMap<String, Validation>();

  // 枚举每一列和字段的对应关系
  Field[] fields = annoClass.getDeclaredFields();
  for (Field field : fields) {
   boolean hasAnnotation = field.isAnnotationPresent(ExcelAnno.class);
   // 有注解的才从Excel读取
   if (hasAnnotation) {
    ExcelAnno anno = field.getAnnotation(ExcelAnno.class);
    Class valiClass = anno.validationClass();
    Validation validation = ValidationFactory
      .getValidation(valiClass);
    String fieldName = field.getName();
    mapping.put(fieldName, validation);
   }
  }
  return mapping;
 }

 public List<Object> getResult() {
  return result;
 }

 public void setResult(List<Object> result) {
  this.result = result;
 }

 public Class<?> getExcelVOs() {
  return excelVOs;
 }

 public void setExcelVOs(Class<?> excelVOs) {
  this.excelVOs = excelVOs;
 }

 public String getEdrReason() {
  return edrReason;
 }

 public void setEdrReason(String edrReason) {
  this.edrReason = edrReason;
 }

分享到:
评论

相关推荐

    Sax解析XML文件解析

    2. **设置事件处理器**:通过`SAXParser`的`setHandler`方法设置一个实现了`ContentHandler`接口的对象,这个对象将处理SAX解析过程中触发的事件。 3. **解析XML**:调用`parse`方法,传入XML文件的输入流或URL,...

    Java SAX解析Xml文档Demo

    // 使用工厂创建SAX解析器 SAXParser saxParser = factory.newSAXParser(); // 创建自定义的事件处理器 SaxDemoHandler handler = new SaxDemoHandler(); // 加载XML文件并开始解析 File inputFile = new ...

    java解析xml数据---sax解析器

    在主函数中,我们设置解析工厂,创建SAX解析器,并使用它来解析`person.xml`文件。 SAX解析器的另一个重要概念是实体解析器(EntityResolver),它可以处理XML文档中的外部实体引用。如果XML文件包含外部DTD(文档...

    Servlet利用SAX解析XML文档

    4. **创建SAX解析器**:使用`SAXParserFactory`的`newInstance()`方法创建一个解析器工厂,然后调用`newSAXParser()`方法生成SAX解析器实例。 5. **实现ContentHandler**:创建一个实现了`org.xml.sax....

    android使用SAX解析xml

    5. **创建SAX解析器处理类** - 在`DefaultHandler`子类中,`startElement()`方法会在遇到元素开始标签时调用,可以记录当前元素的名称。 - `endElement()`方法在元素结束时调用,可用于结束当前元素的处理。 - `...

    dom4j下sax解析xml

    相比之下,SAX解析器采用事件驱动模型,逐行读取XML文档,遇到元素、属性等结构时触发相应的事件。这种方法不将整个文档加载到内存,因此更适用于处理大型或内存受限的环境。然而,由于SAX是基于事件的,它不提供...

    sax解析xml尤其是获取元素的值或者内容

    在使用SAX解析XML前,需要创建一个解析器实例。Java中,可以使用`SAXParserFactory`来生成`SAXParser`,然后调用`parse()`方法解析XML文件。例如: ```java SAXParserFactory factory = SAXParserFactory.new...

    XML通过sax解析JSON格式

    SAX解析器以流式方式处理XML,当遇到文档的不同部分(如开始标签、结束标签、文本节点等)时,会触发相应的事件处理器。我们可以利用这些事件来构建JSON对象。 描述中指出,示例代码中的类可以稍作修改以实现通用性...

    天气预报接口,通过sax 解析接口数据

    接下来,我们将深入探讨天气预报接口、SAX解析以及如何处理XML数据。 首先,天气预报接口是一个API(Application Programming Interface),它提供了获取当前或未来天气信息的途径。这些接口通常由气象服务机构提供...

    SAX解析超大XML文件 示例代码

    SAX解析器逐行读取XML文件,只在需要时处理数据,显著降低了内存需求。 SAX解析的核心在于事件驱动模型。当解析器读取XML文件时,遇到开始元素、结束元素、字符数据等,它会触发相应的事件,并调用预先注册的处理器...

    数据sax解析

    1. **初始化解析器**:程序首先创建一个SAX解析器实例,并注册事件处理器(ContentHandler)。 2. **设置事件处理器**:事件处理器包含一系列回调方法,如`startElement()`、`endElement()`、`characters()`等,当...

    sax解析Excel

    2. 创建事件处理器:SAX解析需要一个事件处理器,它会在解析过程中触发特定事件,例如开始读取工作表、读取单元格等。你需要创建一个实现`XSSFSheetXMLHandler.SheetContentsHandler`接口的类,覆盖其方法来处理这些...

    一个关于sax解析xml的demo

    SAX解析的基本原理是读取XML文档,当遇到文档的开始、结束、元素、属性等结构时,会触发相应的事件处理器方法。程序员通过实现SAX解析器的回调接口,为这些事件编写处理代码,从而解析XML数据。以下是一些关键的SAX...

    java中的sax解析方案

    1. 创建SAX解析器工厂:`SAXParserFactory factory = SAXParserFactory.newInstance();` 2. 配置和获取解析器:`SAXParser parser = factory.newSAXParser();` 3. 创建自定义的事件处理器:`class MyHandler extends...

    [Android]使用SAX解析XML文件

    2. 创建SAX解析器:使用`SAXParserFactory`创建`SAXParser`实例。这一步会初始化解析器,并设置解析行为。 ```java SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); SAXParser saxParser =...

    SAX解析XML实例

    首先,我们需要了解SAX解析的基本步骤: 1. **创建解析器**:使用`SAXParserFactory`来创建`SAXParser`实例。这个工厂类是JAXB的一部分,允许我们配置解析器的行为。 ```java SAXParserFactory factory = ...

    SAX解析.pdf

    SAX解析是一种流式的XML解析方式,它使用了一种基于事件的模型来处理XML文档。开发者不需要在内存中构建整个文档的树形结构,而是通过响应XML解析器发出的事件来处理XML文档。这种方式特别适合处理大型的XML文件,...

    SAX解析网络编程

    SAX解析器的工作原理是逐行读取XML文档,当遇到特定的XML元素时,如开始标签、结束标签、属性等,会触发相应的事件处理器方法。这种方法与DOM(Document Object Model)解析不同,DOM一次性加载整个XML文档到内存,...

    Sax解析范例

    SAX(Simple API for XML)是一种轻量级的XML解析方式,它以事件驱动的方式处理XML文档。在SAX解析中,XML文档被...通过理解SAX解析的工作原理和编写适当的事件处理器,开发者可以有效地从XML文件中提取所需的信息。

    android sax解析创建xml源码

    5. 最后,创建SAX解析器实例,设置我们的处理器,并调用`parse`方法开始解析XML。 ```java public class MyHandler extends DefaultHandler { @Override public void startElement(String uri, String localName,...

Global site tag (gtag.js) - Google Analytics