java 文件解析成JSON数据(其三)

 个人用途,用于将数据解析成json格式使用

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.gta.edu.sdk.util.StringUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.ss.usermodel.BuiltinFormats;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;

import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author y
 * @create 2018-01-18 14:28
 * @desc POI读取excel有两种模式,一种是用户模式,一种是事件驱动模式
 * 采用SAX事件驱动模式解决XLSX文件,可以有效解决用户模式内存溢出的问题,
 * 该模式是POI官方推荐的读取大数据的模式,
 * 在用户模式下,数据量较大,Sheet较多,或者是有很多无用的空行的情况下,容易出现内存溢出
 * <p>
 * 用于解决.xlsx2007版本大数据量问题
 **/
public class ExcelXlsxReader extends DefaultHandler {

    /**
     * 单元格中的数据可能的数据类型
     */
    enum CellDataType {
        BOOL, ERROR, FORMULA, INLINESTR, SSTINDEX, NUMBER, DATE, NULL
    }

    /**
     * 共享字符串表
     */
    private SharedStringsTable sst;

    /**
     * 上一次的内容
     */
    private String lastContents;

    /**
     * 文件的绝对路径
     */
    private String filePath = "";

    /**
     * 工作表索引
     */
    private int sheetIndex = 0;

    /**
     * sheet名
     */
    private String sheetName = "";

    /**
     * 一行内cell集合
     */
    private List<String> cellList = new ArrayList<>();
    /**
     * 单个sheet表的列头集合
     */
    private List<String> columnList;

    /**
     * 单个sheet表的每列的数据类型
     */
    private List<String> columnType;
    //存储sheet表每行
    private JSONObject objSheet;
    //单个sheet表的数据
    private JSONArray arrSheet = new JSONArray();

    //保存所有sheet表的数据
    private JSONArray tables = new JSONArray();
    //保存所有sheet名称
    public List<String> sheetNames = new ArrayList<>();

    /**
     * 字符串标识
     */
    private boolean nextIsString;

    /**
     * 当前行
     */
    private int curRow = 1;


    private int curSize;

    /**
     * 当前列
     */
    private int curCol = 0;

    private int column = 1;

    /**
     * T元素标识
     */
    private boolean isTElement;


    /**
     * 异常信息,如果为空则表示没有异常
     */
    private String exceptionMessage;

    /**
     * 单元格数据类型,默认为字符串类型
     */
    private CellDataType nextDataType = CellDataType.SSTINDEX;

    private final DataFormatter formatter = new DataFormatter();

    /**
     * 单元格日期格式的索引
     */
    private short formatIndex;

    /**
     * 日期格式字符串
     */
    private String formatString;

    //定义前一个元素和当前元素的位置,用来计算其中空的单元格数量,如A6和A8等
    private String preRef = null, ref = null;
    
    //定义该文档一行最大的单元格数,用来补全一行最后可能缺失的单元格
    private String maxRef = null;

    /**
     * 单元格
     */
    private StylesTable stylesTable;

    /**
     * 有效数据矩形区域,A1:Y2
     */
    private String dimension;
    /**
     * 根据dimension得出每行的数据长度
     */
    private int longest;
    /**
     * 上个有内容的单元格id,判断空单元格
     */
    private String lastCellid;
    /**
     * 上一行id, 判断空行
     */
    private String lastRowid;


    /**
     * 遍历工作簿中所有的电子表格
     * 并缓存在mySheetList中
     *
     * @param file
     * @throws Exception
     */
    public JSONArray process(File file) throws Exception {
        //filePath = filename;
        tables.clear();
        sheetNames.clear();
        //File file=new File(filename);
        OPCPackage pkg = OPCPackage.open(file);
        XSSFReader xssfReader = new XSSFReader(pkg);
        stylesTable = xssfReader.getStylesTable();
        SharedStringsTable sst = xssfReader.getSharedStringsTable();
        XMLReader parser = this.fetchSheetParser(sst);
        //Iterator<InputStream> sheets = xssfReader.getSheetsData();
        XSSFReader.SheetIterator sheets = (XSSFReader.SheetIterator) xssfReader.getSheetsData();
        while (sheets.hasNext()) { //遍历sheet
            curRow = 1; //标记初始行为第一行
            curSize = 0;
            arrSheet.clear();//清除历史数据
            if (columnList != null) {
                columnList.clear();
            }
            sheetIndex++;
            InputStream sheet = sheets.next(); //sheets.next()和sheets.getSheetName()不能换位置,否则sheetName报错
            sheetName = sheets.getSheetName();
            sheetNames.add(sheetName);//存储所有sheet名称
            InputSource sheetSource = new InputSource(sheet);
            parser.parse(sheetSource); //解析excel的每条记录,在这个过程中startElement()、characters()、endElement()这三个函数会依次执行
            sheet.close();
            objSheet = new JSONObject();
            JSONArray json = (JSONArray) arrSheet.clone();
            objSheet.put(sheetName, json);
            //总数据
            tables.add(objSheet);
        }
        return tables; //返回该excel文件的总行数,不包括首列和空行
    }

    public XMLReader fetchSheetParser(SharedStringsTable sst) throws SAXException {
        XML
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值