java解析20万Excel

 目前java项目导入Excel文件,处理少量数据时使用Workbook解析没有问题,但在遇到海量数据时就会崩溃,查阅资料结合别人的代码自己也写了一个实例。

先看结论再看代码:

    1.优点:灵活,如有多个不同的Excel表,可以写多个ExcelXXXReader,例如我有三个表,Coupon,Qa,Order,那我就对应ExcelCouponReader,ExcelQaReader,ExcelOrderReader,再新增类型表格,只需要对应新增Reader就可以了。

    2 缺点:解析速度慢,对比别人写的工具类,100W,1000W的数据,只需要10S,20S,抱歉我20个字段,ThinkPad,20W的数据需要80s。

    3 想省事的话,第一第二段代码直接粘贴复制,将其中的实体类替换成自己的就可以了。

代码部分:工具分为两个部分,一个是对读取Excel表格,另一个是将Excel中的字段一一解析到对应的实体类中。

import org.apache.log4j.Logger;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.SharedStringsTable;
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.InputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
 
/**
 * package 
 * Description:用于解析大数据量的EXCEL文件工具类,可以解析少量的emoji表情的,如有昵称,建议将该字段删除
 * Date:
 * Author: 
 **/
public abstract  class XxlsAbstractReader extends DefaultHandler  {
 
    private static final Logger logger = Logger.getLogger(XxlsAbstractReader.class);
 
    private SharedStringsTable sst;
    private String lastContents;
    private boolean nextIsString;
 
    private int sheetIndex = -1;
    private List<Object> rowlist = new ArrayList<Object>();
    private int curRow = 0; // 当前行
    private int curCol = 0; // 当前列索引
    private int preCol = 0; // 上一列列索引
    private int titleRow = 0; // 标题行,一般情况下为0
    private int rowsize = 0; // 列数
 
    // excel记录行操作方法,以sheet索引,行索引和行元素列表为参数,对sheet的一行元素进行操作,元素为String类型
    public abstract void optRows(int sheetIndex, int curRow, List<Object> rowlist) throws SQLException;
 
    // 只遍历一个sheet,其中sheetId为要遍历的sheet索引,从1开始,1-3
 
    /**
     * @param filename
     * @param sheetId sheetId为要遍历的sheet索引,从1开始,1-3
     * @throws Exception
     */
    public void processOneSheet(String filename, int sheetId) throws Exception {
        OPCPackage pkg = OPCPackage.open(filename);
        XSSFReader r = new XSSFReader(pkg);
        SharedStringsTable sst = r.getSharedStringsTable();
 
        XMLReader parser = fetchSheetParser(sst);
 
        // rId2 found by processing the Workbook
        // 根据 rId# 或 rSheet# 查找sheet
        InputStream sheet2 = r.getSheet("rId" + sheetId);
        sheetIndex++;
        InputSource sheetSource = new InputSource(sheet2);
        parser.parse(sheetSource);
        sheet2.close();
    }
 
    /**
     * 遍历 excel 文件
     */
    public void process(String filename) throws Exception {
        OPCPackage pkg = OPCPackage.open(filename);
        XSSFReader r = new XSSFReader(pkg);
        SharedStringsTable sst = r.getSharedStringsTable();
 
        XMLReader parser = fetchSheetParser(sst);
 
        Iterator<InputStream> sheets = r.getSheetsData();
        while (sheets.hasNext()) {
            curRow = 0;
            sheetIndex++;
            InputStream sheet = sheets.next();
            InputSource sheetSource = new InputSource(sheet);
            parser.parse(sheetSource);
            sheet.close();
        }
    }
 
    /**
     * 遍历 excel 文件
     */
    public void process(InputStream in) throws Exception {
        OPCPackage pkg = OPCPackage.open(in);
        XSSFReader r = new XSSFReader(pkg);
        SharedStringsTable sst = r.getSharedStringsTable();
 
        XMLReader parser = fetchSheetParser(sst);
 
        Iterator<InputStream> sheets = r.getSheetsData();
        while (sheets.hasNext()) {
            curRow = 0;
            sheetIndex++;
            InputStream sheet = sheets.next();
            InputSource sheetSource = new InputSource(sheet);
            parser.parse(sheetSource);
            sheet.close();
        }
    }
 
    public XMLReader fetchSheetParser(SharedStringsTable sst) throws SAXException {
        XMLReader parser = XMLReaderFactory.createXMLReader();
        // .createXMLReader("org.apache.xerces.parsers.SAXParser");
        this.sst = sst;
        parser.setContentHandler(this);
        return parser;
    }
 
    public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
        // c => 单元格
        if ("c".equals(name)) {
            // 如果下一个元素是 SST 的索引,则将nextIsString标记为true
            String cellType = attributes.getValue("t");
            String rowStr = attributes.getValue("r");
            curCol = this.getRowIndex(rowStr);
            if (cellType != null && "s".equals(cellType)) {
                nextIsString = true;
            } else {
                nextIsString = false;
            }
        }
        // 置空
        lastContents = "";
    }
 
    public void endElement(String uri, String localName, String name) throws SAXException {
        // 根据SST的索引值的到单元格的真正要存储的字符串
        // 这时characters()方法可能会被调用多次
        if (nextIsString) {
            try {
                int idx = Integer.parseInt(lastContents);
                lastContents = new XSSFRichTextString(sst.getEntryAt(idx)).toString();
            } catch (Exception e) {
 
            }
        }
        // v => 单元格的值,如果单元格是字符串则v标签的值为该字符串在SST中的索引
        // 将单元格内容加入rowlist中,在这之前先去掉字符串前后的空白符
        if ("v".equals(name)) {
            String value = lastContents.trim();
            value = "".equals(value) ? " " : value;
            int cols = curCol - preCol;
            if (cols > 1) {
                for (int i = 0; i < cols - 1; i++) {
                    rowlist.add(preCol, "");
                }
            }
            preCol = curCol;
            rowlist.add(curCol - 1, value);
        } else {
            // 如果标签名称为 row ,这说明已到行尾,调用 optRows() 方法
            if ("row".equals(name)) {
                int tmpCols = rowlist.size();
                if (tmpCols > 0) {
                    if (curRow > this.titleRow && tmpCols < this.rowsize) {
                        for (int i = 0; i < this.rowsize - tmpCols; i++) {
                            rowlist.add(rowlist.size(), "");
                        }
                    }
                    try {
                        optRows(sheetIndex, curRow, rowlist);
                    } catch (SQLException e) {
                        logger.error("endElement error", e);
                    }
                } else {// 跳过空白行
                    logger.info("jump blank row ,curRow:" + (curRow + 1));
                }
                if (curRow == this.titleRow) {
                    this.rowsize = rowlist.size();
                    if (this.rowsize == 0) {
                        throw new RuntimeException("excel 未被编辑或者内容为空");
                    }
                }
                rowlist.clear();
                curRow++;
                curCol = 0;
                preCol = 0;
            }
        }
    }
    public void characters(char[] ch, int start, int length) throws SAXException {
        // 得到单元格内容的值
        lastContents += new String(ch, start, length);
    }
    // 得到列索引,每一列c元素的r属性构成为字母加数字的形式,字母组合为列索引,数字组合为行索引,
    // 如AB45,表示为第(A-A+1)*26+(B-A+1)*26列,45行
    public int getRowIndex(String rowStr) {
        rowStr = rowStr.replaceAll("[^A-Z]", "");
        byte[] rowAbc = rowStr.getBytes();
        int len = rowAbc.length;
        float num = 0;
        for (int i = 0; i < len; i++) {
            num += (rowAbc[i] - 'A' + 1) * Math.pow(26, len - i - 1);
        }
        return (int) num;
    }
    public int getTitleRow() {
        return titleRow;
    }
    public void setTitleRow(int titleRow) {
        this.titleRow = titleRow;
    }
    public int getSheetIndex() {
        return sheetIndex;
    }
}

package com.bootdo.witdbct.operateVisu.importData;

import com.bootdo.common.config.ApplicationContextRegister;
import com.bootdo.common.utils.ShiroUtils;
import com.bootdo.witdbct.operateVisu.dao.DbctRPoperMapper;
import com.bootdo.witdbct.operateVisu.domain.DbctRPoper;
import com.bootdo.witdbct.system.domain.UserDO;
import com.yd.common.runtime.CIPRuntime;
import org.apache.commons.lang.time.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * @program: bootdo
 * @description: 使用工具类对EXCEL文件进行解析并映射
 * @author: WangChen
 * @create: 2019-03-06 09:22
 **/


public class ExcelReader extends XxlsAbstractReader {

    /*@Autowired
    private DbctRPoperMapper mapper;*/
    private static ExcelReader excelRedder;
    DbctRPoperMapper poperMapper = ApplicationContextRegister.getBean(DbctRPoperMapper.class);
   /* @PostConstruct
    public void init() {
        excelRedder = this;
        excelRedder.mapper = this.mapper;
    }*/

    /*List<DbctRPoper> poperL = getPoperL();

    Map<String, String> dbctMaps = dbctMap(); */

    List<Map<String, Object>> poperL = poperMapper.searchPoper();
    List<Map<String, Object>> zzList = poperMapper.queryZZ();
    List<String> dbctTee =dbctMap(poperL);
    List<String> dbctList = dbctMap(zzList);


    //private List<Map<String,Object>> voList = new ArrayList<>();
    private List<DbctRPoper> voList = new ArrayList<>();
    private List<String> curRowList = new ArrayList<>();

    public ExcelReader() {
    }

    @Override
    public void optRows(int sheetIndex, int curRow, List<Object> rowlist) throws SQLException {
        if (curRow == 0) {
            return;
        }
        int sheet =  sheetIndex+1;
        DbctRPoper poper = new DbctRPoper();
        UserDO user = ShiroUtils.getUser();

        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DAY_OF_MONTH, 1);
        String nextDay = sf.format(c.getTime())+" 00:00:00";//次日

        poper.setDbct(Integer.parseInt((String)rowlist.get(0)));
        poper.setDbctName((String)rowlist.get(1));
        poper.setSte_par(new BigDecimal((String)rowlist.get(2)));
        poper.setSor_par(new BigDecimal((String)rowlist.get(3)));
        poper.setLoading_p_end1(new BigDecimal((String)rowlist.get(4)));
        poper.setLoading_p_color1(changeColorEnFromZh(rowlist.get(5)));
        poper.setLoading_p_end2(new BigDecimal((String)rowlist.get(6)));
        poper.setLoading_p_color2(changeColorEnFromZh(rowlist.get(7)));
        poper.setLoading_p_end3(new BigDecimal((String)rowlist.get(8)));
        poper.setLoading_p_color3(changeColorEnFromZh(rowlist.get(9)));
        poper.setUnload_ot1(new BigDecimal((String)rowlist.get(10)));
        poper.setUnload_ot_color1(changeColorEnFromZh(rowlist.get(11)));
        poper.setUnload_ot2(new BigDecimal((String)rowlist.get(12)));
        poper.setUnload_ot_color2(changeColorEnFromZh(rowlist.get(13)));
        poper.setStock_warning(new BigDecimal((String)rowlist.get(14)));
        poper.setStock_warning_color(changeColorEnFromZh(rowlist.get(15)));
        poper.setStock_full(new BigDecimal((String)rowlist.get(16)));
        poper.setStock_full_color(changeColorEnFromZh(rowlist.get(17)));
        poper.setTake_effect_time(nextDay);

        if(StringUtils.isBlank(poper.getDbct().toString())){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据分拨编码为空!");
        }

        if(dbctTee.contains(poper.getDbct().toString())){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据再数据库中已存在!");
        }
        if(!dbctList.contains(poper.getDbct().toString())){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据分拨编码不存在!");
        }
        if(StringUtils.isBlank((String)rowlist.get(2))){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据装卸工目标能效为空!");
        }
        if(StringUtils.isBlank((String)rowlist.get(3))){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据分拣工目标能效为空!");
        }
        if(StringUtils.isBlank((String)rowlist.get(4))){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据装车离时效截止点1为空!");
        }else if( Integer.parseInt((String)rowlist.get(4)) < 0){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据装车离时效截止点1数据小于0!");
        }
        if(StringUtils.isBlank((String)rowlist.get(5))){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据装车离时效截止点1显示颜色为空!");
        }
        if(StringUtils.isBlank((String)rowlist.get(6))){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据装车离时效截止点2为空!");
        }else if( Integer.parseInt((String)rowlist.get(6)) < 0){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据装车离时效截止点2数据小于0!");
        }
        if(StringUtils.isBlank((String)rowlist.get(7))){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据装车离时效截止点2显示颜色为空!");
        }
        if(StringUtils.isBlank((String)rowlist.get(8))){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据装车离时效截止点3为空!");
        }else if( Integer.parseInt((String)rowlist.get(8)) < 0){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据装车离时效截止点3数据小于0!");
        }
        if(StringUtils.isBlank((String)rowlist.get(9))){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据装车离时效截止点3显示颜色为空!");
        }
        if(StringUtils.isBlank((String)rowlist.get(10))){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据卸车超时1为空!");
        }else if( Integer.parseInt((String)rowlist.get(10)) < 0){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据卸车超时1数据小于0!");
        }
        if(StringUtils.isBlank((String)rowlist.get(11))){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据卸车超时1显示颜色为空!");
        }
        if(StringUtils.isBlank((String)rowlist.get(12))){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据卸车超时2为空!");
        }else if( Integer.parseInt((String)rowlist.get(12)) < 0){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据卸车超时2数据小于0!");
        }
        if(StringUtils.isBlank((String)rowlist.get(13))){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据卸车超时2显示颜色为空!");
        }
        if(StringUtils.isBlank((String)rowlist.get(14))){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据库存预警为空!");
        }else if( Integer.parseInt((String)rowlist.get(14)) < 0 || Integer.parseInt((String)rowlist.get(14)) > 100){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据库存预警数据小于0!");
        }
        if(StringUtils.isBlank((String)rowlist.get(15))){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据库存预警显示颜色为空!");
        }
        if(StringUtils.isBlank((String)rowlist.get(16))){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据库存爆仓为空!");
        }else if( Integer.parseInt((String)rowlist.get(16)) < 0 || Integer.parseInt((String)rowlist.get(14)) > 100){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据库存爆仓数据小于0!");
        }
        if(StringUtils.isBlank((String)rowlist.get(17))){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据库存爆仓显示颜色为空!");
        }



        /*if(poperL.contains(poper)){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据在数据库中已存在!");
        }

        if(!StringUtils.equals(poper.getDbctName(),dbctMaps.get(poper.getDbct().toString()))){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据分拨名称不匹配!");
        }
        if(StringUtils.equals(poper.getStevedore().toString(),"")||StringUtils.equals(poper.getStevedore().toString(),null)){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据装卸工为空!");
        }
        if(StringUtils.equals(poper.getPalletizer().toString(),"")||StringUtils.equals(poper.getPalletizer().toString(),null)){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据分拣工为空!");
        }*/
        poper.setEntry_man(user.getUserName());
        poper.setEntry_man_id(user.getUserId());
        poper.setImStatus("1");
        if(voList.contains(poper)){
            curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据重复!");
        }
        voList.add(poper);



        //voList.add(poper);
    }
    public List<DbctRPoper> getExcelCouponList() {
        return voList;
    }

    public List<String> getExcelcurRowList() {
        return curRowList;
    }



    /**
     * 日期类型字段会被解析成1900至今的毫秒数,自己写了一个工具,将毫秒数转换为日期,小时和分钟会丢失精度
     * 此方法可自己重写!!!精度不够
     * @param dataString
     * @return
     */
    public static String numToString(String dataString) {
        if ("" != dataString && null != dataString) {
            String str = null;
            if (!dataString.contains(".")) {
                Calendar calendar = new GregorianCalendar(1900,0,-1);
                Date d1 = calendar.getTime();
                Date d2 = DateUtils.addDays(d1,Integer.valueOf(dataString));
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm");
                str = sdf.format(d2);
            }else {
                String string = dataString.substring(0,dataString.lastIndexOf("."));
                Calendar calendar = new GregorianCalendar(1900,0,-1);
                Date d1 = calendar.getTime();
                Date d2 = DateUtils.addDays(d1,Integer.valueOf(string));
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm");
                str = sdf.format(d2);
            }
            return str;
        }
        return "";
    }


    /**
     * 将分拨数据组成Map,以便验证使用
     * @return
     */
    private List<String> dbctMap(List<Map<String, Object>> zzList){
        List<String> list = new ArrayList<>();
        for (Map<String, Object> map : zzList) {
            list.add(String.valueOf(map.get("bm")));
        }
        return list;
    }

    /*private List<Map<String,Object>> getPoperL(){
        DbctRPoperMapper poperMapper = ApplicationContextRegister.getBean(DbctRPoperMapper.class);
        List<Map<String,Object>> dbctRPopers = poperMapper.searchPoper();
        return dbctRPopers;
    }*/

    /**
     * 显示颜色中英文转换
     * @param color
     * @return
     */
    private String changeColorEnFromZh(Object color){
        String col = "";
        String str = (String)color;
        if(StringUtils.equals(str,"红色")){
            col = "red";
        }
        if(StringUtils.equals(str,"黄色")){
            col = "yellow";
        }
        if(StringUtils.equals(str,"绿色")){
            col = "green";
        }
        return col;
    }

}

 

使用方式:

public static void main(String[] args) {
   

 MultipartFile[] file;//此处为前台上传的多个文件,也可改为单个文件处理
try {

    for(MultipartFile multipartFile : file){
        String fileName = multipartFile.getOriginalFilename();
        InputStream inputStream = multipartFile.getInputStream();
        ExcelReader excelReader = new ExcelReader();
        excelReader.process(inputStream);
        //解析到List,准备验证保存
        List<Map<String,Object>> excelCouponList = excelReader.getExcelCouponList();
        if(excelCouponList.size() > 100000){
            msg.setSuccess(false);
            msg.setMessage("导入数据不能超过十万条!");
            return msg;
        }

        int code = service.insertAll(excelCouponList);
        if(code > 0){
            msg.setSuccess(true);
            msg.setMessage("文件导入成功!");
        }else{
            msg.setSuccess(false);
            msg.setMessage("文件导入失败!");
        }

    }
} catch (Exception e) {
    msg.setSuccess(false);
    msg.setMessage("数据格式错误!");
}


 
}

 

项目中具体使用(前台):

js:

$(function (){

    //0.初始化fileinput
    var oFileInput = new FileInput();
    oFileInput.Init("txt_file", ctx+"oper/importFile");

});


var FileInput = function () {
    var oFile = new Object();

    //初始化fileinput控件(第一次初始化)
    oFile.Init = function(ctrlName, uploadUrl) {
        var control = $('#' + ctrlName);

        //初始化上传控件的样式
        control.fileinput({
            language: 'zh', //设置语言
            uploadUrl: uploadUrl, //上传的地址
            allowedFileExtensions:["xls", "xlsx"],//接收的文件后缀
            showUpload: true, //是否显示上传按钮
            showCaption: false,//是否显示标题
            //showPreview:true,
            browseClass: "btn btn-primary", //按钮样式
            //dropZoneEnabled: false,//是否显示拖拽区域
            //minImageWidth: 50, //图片的最小宽度
            //minImageHeight: 50,//图片的最小高度
            //maxImageWidth: 1000,//图片的最大宽度
            //maxImageHeight: 1000,//图片的最大高度
            //maxFileSize: 0,//单位为kb,如果为0表示不限制文件大小
            //minFileCount: 0,
            maxFileCount: 10, //表示允许同时上传的最大文件个数
            enctype: 'multipart/form-data',
            validateInitialCount:true,
            previewFileType:["xls", "xlsx"],
            previewFileIconSettings: {
                'docx': '<i ass="fa fa-file-word-o text-primary"></i>',
                'xlsx': '<i class="fa fa-file-excel-o text-success"></i>',
                'xls': '<i class="fa fa-file-excel-o text-success"></i>',
                'pptx': '<i class="fa fa-file-powerpoint-o text-danger"></i>',
                'jpg': '<i class="fa fa-file-photo-o text-warning"></i>',
                'pdf': '<i class="fa fa-file-archive-o text-muted"></i>',
                'zip': '<i class="fa fa-file-archive-o text-muted"></i>',
            },
            msgFilesTooMany: "选择上传的文件数量({n}) 超过允许的最大数值{m}!",
        });

        //导入文件上传完成之后的事件
        $("#txt_file").on("fileuploaded", function (event, data, previewId, index) {
            //$("#import").modal("hide");
            //console.log(data);
            if(data.response.success == true){
                //alert(data.files[index].name + "上传成功!");
                //layer.msg(data.files[index].name + "上传成功!", {icon: 6});
                var datasss = "";
                for(var i = 0;i<data.files.length;i++){
                    datasss+=data.files[i].name;
                }
                swal({title: "成功", text: datasss + "上传成功!", type: "success"});
                //关闭
               // $(".close").click();
            }else{
               //alert(data.files[index].name + "上传失败!" + data.response.message);
                //layer.msg(data.files[index].name + "上传失败!" + data.response.message, {icon: 5});
                var tishi = data.files[index].name + "上传失败!";
                //$(tishi).appendTo($("#tishi"));
                var resData = data.response.message;
                var result = resData.text;
                var arr = [];
                for(var i = 0;i<result.length;i++){
                    arr.push('<p>'+result[i]+'<p/>');
                }
                var str = arr.join('');
                $(str).appendTo($('#importInfoBody'));
                $("#importInfo").modal();
                //重置
                $("#txt_file").fileinput("clear");
                $("#txt_file").fileinput("reset");
                $('#txt_file').fileinput('refresh');
                $('#txt_file').fileinput('enable');
            }

        });
    }
    return oFile;
};

html:

<!-- 模态框(Modal) -->
<!--导入数据操作层-->
<form>
    <div class="modal fade" id="import" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" style="z-index:9992;">
        <div class="modal-dialog modal-lg" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
                    <h4 class="modal-title" id="myModalLabel">请选择Excel文件</h4>
                </div>
                <div class="modal-body">
                    <a href="#" class="form-control" style="border:none;color: blue;text-decoration:underline;" onclick="downloadTemplate()">下载导入模板</a>
                    <input type="file" name="txt_file" id="txt_file" multiple  class="file-loading" />
                </div></div>
        </div>
    </div>
</form>

<!--导入消息提示框-->
<div class="modal fade" id="importInfo">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h3 id="tishi">提示 </h3>
            </div>
            <div class="modal-body" id="importInfoBody">

            </div>
            <div class="modal-footer">
                <button class="btn btn-info" data-dismiss="modal">关闭</button>
            </div>
        </div>
    </div>
</div>

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 解析复杂表格的 Excel 文件通常需要使用第三方库,比如 Apache POI 和 EasyExcel。 其中,Apache POI 是一个流行的 Java 库,可以读取和写入 Microsoft Office 格式文件,包括 Excel、Word 和 PowerPoint。它提供了丰富的 API,可以用于解析各种类型的 Excel 文件,包括复杂表格和数据格式。 以下是一个使用 Apache POI 解析 Excel 文件的示例代码: ```java import org.apache.poi.ss.usermodel.*; import java.io.File; import java.io.FileInputStream; import java.io.IOException; public class ExcelParser { public static void main(String[] args) throws IOException { // 创建输入流,读取 Excel 文件 FileInputStream inputStream = new FileInputStream(new File("path/to/excel/file.xlsx")); // 创建工作簿对象 Workbook workbook = WorkbookFactory.create(inputStream); // 获取第一个工作表 Sheet sheet = workbook.getSheetAt(0); // 遍历行 for (Row row : sheet) { // 遍历单元格 for (Cell cell : row) { // 获取单元格的值 String value = getCellValue(cell); System.out.print(value + "\t"); } System.out.println(); } // 关闭工作簿和输入流 workbook.close(); inputStream.close(); } // 获取单元格的值 private static String getCellValue(Cell cell) { if (cell == null) { return ""; } switch (cell.getCellType()) { case STRING: return cell.getStringCellValue(); case NUMERIC: if (DateUtil.isCellDateFormatted(cell)) { return cell.getDateCellValue().toString(); } else { return String.valueOf(cell.getNumericCellValue()); } case BOOLEAN: return String.valueOf(cell.getBooleanCellValue()); case FORMULA: return cell.getCellFormula(); default: return ""; } } } ``` 在上述代码中,首先创建一个输入流,用于读取 Excel 文件。然后通过 `WorkbookFactory.create()` 方法创建一个工作簿对象,再通过 `Workbook.getSheetAt()` 方法获取第一个工作表。 接着,通过遍历行和单元格,可以逐个获取单元格的值。在 `getCellValue()` 方法中,通过 `Cell.getCellType()` 方法判断单元格类型,并返回相应的值。注意,对于日期类型的单元格,需要使用 `DateUtil.isCellDateFormatted()` 方法判断单元格是否为日期格式,然后再使用 `Cell.getDateCellValue()` 方法获取日期值。 最后,别忘了在程序结束时关闭工作簿和输入流。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值