精华内容
下载资源
问答
  • java解析excel

    2016-08-19 17:59:56
    java解析excel
  • java解析Excel

    2014-02-27 09:33:59
    java解析Excel
  • java 解析excel

    2013-09-30 15:00:54
    java Workbook 解析excel文件
  • Java 解析excel

    2016-03-28 16:58:50
    Java代码来解析通过表格的形式来显示的excel 希望对各位在这方面学习的有所帮助 谢谢
  • JAVA解析Excel

    2017-08-27 22:52:30
    一.Excel解析的几种实现方式 1.JXL(较少使用) 2.POI(常用) 3.FastExcel(基本不用)二.实例 1.JXL(先导入jxl的包 )package com.tiglle.jxl;import java.io.File;import jxl.Workbook; import jxl.write.Label; ...

    一.Excel解析的几种实现方式
    1.JXL(较少使用)

    2.POI(常用)
    问题:The supplied data appears to be in the Office 2007+ XML
    参照:https://blog.csdn.net/you23hai45/article/details/70196897
    大概:判断文件后缀名是xls,还是xlsx,如果是xls,使用HSSFWorkbook;如果是xlsx,使用XSSFWorkbook

    3.FastExcel(基本不用)

    二.实例
    1.JXL生成导出Excel(先导入jxl的包 )

    package com.tiglle.jxl;
    
    import java.io.File;
    
    import jxl.Workbook;
    import jxl.write.Label;
    import jxl.write.WritableSheet;
    import jxl.write.WritableWorkbook;
    
    public class JxlTestOut{
    
        public static void main(String[] args) {
            //创建Excel文件
            File file = new File("e:/jxl_excel.xls");
            try {
                //创建工作薄
                WritableWorkbook workbook = Workbook.createWorkbook(file);
                //创建sheet页
                WritableSheet sheet = workbook.createSheet("sheet名称", 0);
                //一格Label代表一格,用列y和行x定位。new Label(列y,行x,"标题0");
                Label label0 = new Label(0,0,"标题0");
                Label label1 = new Label(1,0,"标题1");
                Label label2 = new Label(2,0,"标题2");
                sheet.addCell(label0);
                sheet.addCell(label1);
                sheet.addCell(label2);
    
                //第二行数据
                Label label3 = new Label(0,1,"内容0");
                Label label4 = new Label(1,1,"内容1");
                Label label5 = new Label(2,1,"内容2");
                sheet.addCell(label3);
                sheet.addCell(label4);
                sheet.addCell(label5);
    
                //写入内容
                workbook.write();
                //关闭流
                workbook.close();
            } catch (Exception e) {
                // TODO: handle exception
            }
        }
    
    }
    jxl_excel.xls:
    标题0 标题1 标题2
    内容0 内容1 内容2
    

    2.JXL解析导入Excel

    package com.tiglle.jxl;
    
    import java.io.File;
    
    import jxl.Cell;
    import jxl.Sheet;
    import jxl.Workbook;
    
    public class JxlTestIn {
    
        public static void main(String[] args) {
            try {
                //指定Excel文件
                File file = new File("E://jxl_excel.xls");
                //创建WorkBook
                Workbook workbook = Workbook.getWorkbook(file);
                //获取工作表sheet页(从第0页开始)
                Sheet sheet0 = workbook.getSheet(0);
                //获取第一页sheet中的数据
                //getCell(y,x);
                Cell cell00 = sheet0.getCell(0, 0);
                System.out.println(cell00.getContents());
                Cell cell10 = sheet0.getCell(1, 0);
                System.out.println(cell10.getContents());
                //关闭流
                workbook.close();
            } catch (Exception e) {
    
            }
        }
    
    }
    结果:
    标题0
    标题1

    3.POI生成导出Excle

    package com.tiglle.poi;
    
    import java.io.File;
    import java.io.FileOutputStream;
    
    import org.apache.poi.hssf.usermodel.HSSFRow;
    import org.apache.poi.hssf.usermodel.HSSFSheet;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    import org.apache.poi.ss.usermodel.Cell;
    
    public class PoiTestOut {
    
        public static void main(String[] args) {
            //创建Excel工作薄
            HSSFWorkbook workbook = new HSSFWorkbook();
    
            //创建一个sheet页
            HSSFSheet sheet0 = workbook.createSheet("第一页");
    
            //创建第一行标题行,从0开始
            HSSFRow row0 = sheet0.createRow(0);
            //创建第一行的第一格(第一列)
            Cell cell00 = row0.createCell(0);
            //设置y0,x0的内容(y,x)
            cell00.setCellValue("标题0");
            //创建第一行的第二格
            Cell cell01 = row0.createCell(1);
            //设置y0,x1的内容
            cell01.setCellValue("标题1");
            //创建第一行的第三格
            Cell cell02 = row0.createCell(2);
            //设置y0,x2的内容
            cell02.setCellValue("标题2");
    
            //创建第二行的内容行
            HSSFRow row1 = sheet0.createRow(1);
            //第二行第一格
            Cell cell10 = row1.createCell(0);
            //设置y1,x0的内容
            cell10.setCellValue("内容0");
            //第二行第二格
            Cell cell11 = row1.createCell(1);
            //设置y1,x1的内容
            cell11.setCellValue("内容1");
            //第二行第一格
            Cell cell12 = row1.createCell(2);
            //设置y1,x2的内容
            cell12.setCellValue("内容2");
    
            //创建第二个sheet页..
            HSSFSheet sheet1 = workbook.createSheet("第二页");
            try {
                //创建Excel文件,并将内容写入(如果路径包含不存在的文件夹,必须创建,不然包找不到文件异常)
                File file = new File("E://poi_excel.xls");
                file.createNewFile();
                //通过文件输出流将内容写入文件
                FileOutputStream outStream = new FileOutputStream(file);
                //将内容写入
                workbook.write(outStream);
    
                //关闭流
                outStream.close();
                workbook.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    
    }
    

    4.POI解析Excel

    package com.tiglle.poi;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.InputStream;
    
    import org.apache.poi.hssf.usermodel.HSSFCell;
    import org.apache.poi.hssf.usermodel.HSSFRow;
    import org.apache.poi.hssf.usermodel.HSSFSheet;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    
    public class PoiTestIn {
    
        public static void main(String[] args) {
            try {
                //指定一个Excel文件
                File file = new File("E://poi_excel.xls");
                //创建Excel,读取文件内容
                InputStream inputStream = new FileInputStream(file);
                HSSFWorkbook workbook = new HSSFWorkbook(inputStream);
                //获取指定sheet页(两种方式)
                //1.通过sheetName获取
                //HSSFSheet sheet = workbook.getSheet("第一页");
                //2.通过索引(页数)获取(从0开始)
                HSSFSheet sheet = workbook.getSheetAt(0);
    
                //获取第一行
                HSSFRow row0 = sheet.getRow(0);
                //获取第一行的第一格(y,x)
                HSSFCell cell00 = row0.getCell(0);
                //获取内容
                String content = cell00.getStringCellValue();
                System.out.println(content);
    
                //获取第二行
                HSSFRow row1 = sheet.getRow(1);
                //获取第二行的第一格(y,x)
                HSSFCell cell10 = row1.getCell(0);
                //获取内容
                String content1 = cell10.getStringCellValue();
                System.out.println(content1);
    
                //获取sheet中最后一行行号
                int lastRowNum = sheet.getLastRowNum();
                //获取一行最后一格号
                int lastCellNum = row1.getLastCellNum();
                System.out.println("lastRowNum="+lastRowNum+",lastCellNum="+lastCellNum);
    
                //关闭流
                workbook.close();
                inputStream.close();
            } catch (Exception e) {
            }
        }
    
    }
    

    5.POI生成和解析高版本的Excel(xlsx后缀结尾)
    生出导出:

    package com.tiglle.poi;
    
    import java.io.File;
    import java.io.FileOutputStream;
    
    import org.apache.poi.ss.usermodel.Cell;
    import org.apache.poi.xssf.usermodel.XSSFRow;
    import org.apache.poi.xssf.usermodel.XSSFSheet;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;
    
    /**
     * 生成高版本你的Excel(xlsx后缀结尾)
     * 低版本使用的HSSF,高版本使用XSSF
     * @author Administrator
     *
     */
    public class PoiHeightVersionExcelOut {
    
        public static void main(String[] args) {
            //创建Excel工作薄
                    XSSFWorkbook workbook = new XSSFWorkbook();
    
                    //创建一个sheet页
                    XSSFSheet sheet0 = workbook.createSheet("第一页");
    
                    //创建第一行标题行,从0开始
                    XSSFRow row0 = sheet0.createRow(0);
                    //创建第一行的第一格(第一列)
                    Cell cell00 = row0.createCell(0);
                    //设置y0,x0的内容(y,x)
                    cell00.setCellValue("标题0");
                    //创建第一行的第二格
                    Cell cell01 = row0.createCell(1);
                    //设置y0,x1的内容
                    cell01.setCellValue("标题1");
                    //创建第一行的第三格
                    Cell cell02 = row0.createCell(2);
                    //设置y0,x2的内容
                    cell02.setCellValue("标题2");
    
                    //创建第二行的内容行
                    XSSFRow row1 = sheet0.createRow(1);
                    //第二行第一格
                    Cell cell10 = row1.createCell(0);
                    //设置y1,x0的内容
                    cell10.setCellValue("内容0");
                    //第二行第二格
                    Cell cell11 = row1.createCell(1);
                    //设置y1,x1的内容
                    cell11.setCellValue("内容1");
                    //第二行第一格
                    Cell cell12 = row1.createCell(2);
                    //设置y1,x2的内容
                    cell12.setCellValue("内容2");
    
                    //创建第二个sheet页..
                    XSSFSheet sheet1 = workbook.createSheet("第二页1");
                    try {
                        //创建Excel文件,并将内容写入(如果路径包含不存在的文件夹,必须创建,不然包找不到文件异常)
                        File file = new File("E://poi_excel1.xlsx");
                        file.createNewFile();
                        //通过文件输出流将内容写入文件
                        FileOutputStream outStream = new FileOutputStream(file);
                        //将内容写入
                        workbook.write(outStream);
    
                        //关闭流
                        outStream.close();
                        workbook.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
        }
    
    }
    

    解析读取

    package com.tiglle.poi;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.InputStream;
    
    import org.apache.poi.xssf.usermodel.XSSFCell;
    import org.apache.poi.xssf.usermodel.XSSFRow;
    import org.apache.poi.xssf.usermodel.XSSFSheet;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;
    /**
     * 解析高版本你的Excel(xlsx后缀结尾)
     * 低版本使用的HSSF,高版本使用XSSF
     * @author Administrator
     *
     */
    public class PoiHeightVersionExcelIn {
    
        public static void main(String[] args) {
            try {
                //指定一个Excel文件
                File file = new File("E://poi_excel.xlsx");
                //创建Excel,读取文件内容
                InputStream inputStream = new FileInputStream(file);
                XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
                //获取指定sheet页(两种方式)
                //1.通过sheetName获取
                //HSSFSheet sheet = workbook.getSheet("第一页");
                //2.通过索引(页数)获取(从0开始)
                XSSFSheet sheet = workbook.getSheetAt(0);
    
                //获取第一行
                XSSFRow row0 = sheet.getRow(0);
                //获取第一行的第一格(y,x)
                XSSFCell cell00 = row0.getCell(0);
                //获取内容
                String content = cell00.getStringCellValue();
                System.out.println(content);
    
                //获取第二行
                XSSFRow row1 = sheet.getRow(1);
                //获取第二行的第一格(y,x)
                XSSFCell cell10 = row1.getCell(0);
                //获取内容
                String content1 = cell10.getStringCellValue();
                System.out.println(content1);
    
                //获取sheet中最后一行行号
                int lastRowNum = sheet.getLastRowNum();
                //获取一行最后一格号
                int lastCellNum = row1.getLastCellNum();
                System.out.println("lastRowNum="+lastRowNum+",lastCellNum="+lastCellNum);
    
                //关闭流
                workbook.close();
                inputStream.close();
            } catch (Exception e) {
            }
        }
    
    }
    结果:
    标题0
    内容0
    lastRowNum=1,lastCellNum=3
    展开全文
  • java解析excel源码

    2018-10-29 12:11:53
    java解析excel,包含java类与jar包,将类与jar添加到项目即可用,excel路径在程序中调整
  • 主要介绍了Java解析Excel内容的方法,实例分析了java解析excel文件的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
  • Java解析excel工具easyexcel 助你快速简单避免OOM

    万次阅读 多人点赞 2018-07-19 15:03:00
    Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及...

    原文链接:http://www.itsleuth.cn/post/javatool-001-easyexcel/

    Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。easyexcel重写了poi对07版Excel的解析,能够原本一个3M的excel用POI sax依然需要100M左右内存降低到KB级别,并且再大的excel不会出现内存溢出,03版依赖POI的sax模式。在上层做了模型转换的封装,让使用者更加简单方便

    easyexcel核心功能

    • 读任意大小的03、07版Excel不会OOM
    • 读Excel自动通过注解,把结果映射为java模型
    • 读Excel支持多sheet
    • 读Excel时候是否对Excel内容做trim()增加容错
    • 写小量数据的03版Excel(不要超过2000行)
    • 写任意大07版Excel不会OOM
    • 写Excel通过注解将表头自动写入Excel
    • 写Excel可以自定义Excel样式 如:字体,加粗,表头颜色,数据内容颜色
    • 写Excel到多个不同sheet
    • 写Excel时一个sheet可以写多个Table
    • 写Excel时候自定义是否需要写表头

    快速使用

    1. JAR包依赖

    使用前最好咨询下最新版,或者到mvn仓库搜索一下easyexcel的最新版

    <dependency>
    	<groupId>com.alibaba</groupId>
    	<artifactId>easyexcel</artifactId>
        <version>{latestVersion}</version>
    </dependency>
    

    2. 读取Excel

    使用easyexcel解析03、07版本的Excel只是ExcelTypeEnum不同,其他使用完全相同,使用者无需知道底层解析的差异。

    无java模型直接把excel解析的每行结果以List返回 在ExcelListener获取解析结果
    读excel代码示例如下:

    
        @Test
        public void testExcel2003NoModel() {
            InputStream inputStream = getInputStream("loan1.xls");
            try {
                // 解析每行结果在listener中处理
                ExcelListener listener = new ExcelListener();
    
                ExcelReader excelReader = new ExcelReader(inputStream, ExcelTypeEnum.XLS, null, listener);
                excelReader.read();
            } catch (Exception e) {
    
            } finally {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    

    ExcelListener示例代码如下:

    
     /* 解析监听器,
     * 每解析一行会回调invoke()方法。
     * 整个excel解析结束会执行doAfterAllAnalysed()方法
     *
     * 下面只是我写的一个样例而已,可以根据自己的逻辑修改该类。
     * @author jipengfei
     * @date 2017/03/14
     */
    public class ExcelListener extends AnalysisEventListener {
    
        //自定义用于暂时存储data。
        //可以通过实例获取该值
        private List<Object> datas = new ArrayList<Object>();
        public void invoke(Object object, AnalysisContext context) {
            System.out.println("当前行:"+context.getCurrentRowNum());
            System.out.println(object);
            datas.add(object);//数据存储到list,供批量处理,或后续自己业务逻辑处理。
            doSomething(object);//根据自己业务做处理
        }
        private void doSomething(Object object) {
            //1、入库调用接口
        }
        public void doAfterAllAnalysed(AnalysisContext context) {
           // datas.clear();//解析结束销毁不用的资源
        }
        public List<Object> getDatas() {
            return datas;
        }
        public void setDatas(List<Object> datas) {
            this.datas = datas;
        }
    }
    

    有java模型映射
    java模型写法如下:

    public class LoanInfo extends BaseRowModel {
        @ExcelProperty(index = 0)
        private String bankLoanId;
        
        @ExcelProperty(index = 1)
        private Long customerId;
        
        @ExcelProperty(index = 2,format = "yyyy/MM/dd")
        private Date loanDate;
        
        @ExcelProperty(index = 3)
        private BigDecimal quota;
        
        @ExcelProperty(index = 4)
        private String bankInterestRate;
        
        @ExcelProperty(index = 5)
        private Integer loanTerm;
        
        @ExcelProperty(index = 6,format = "yyyy/MM/dd")
        private Date loanEndDate;
        
        @ExcelProperty(index = 7)
        private BigDecimal interestPerMonth;
    
        @ExcelProperty(value = {"一级表头","二级表头"})
        private BigDecimal sax;
    }
    

    @ExcelProperty(index = 3)数字代表该字段与excel对应列号做映射,也可以采用 @ExcelProperty(value = {“一级表头”,“二级表头”})用于解决不确切知道excel第几列和该字段映射,位置不固定,但表头的内容知道的情况。

        @Test
        public void testExcel2003WithReflectModel() {
            InputStream inputStream = getInputStream("loan1.xls");
            try {
                // 解析每行结果在listener中处理
                AnalysisEventListener listener = new ExcelListener();
    
                ExcelReader excelReader = new ExcelReader(inputStream, ExcelTypeEnum.XLS, null, listener);
    
                excelReader.read(new Sheet(1, 2, LoanInfo.class));
            } catch (Exception e) {
    
            } finally {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
        }
    

    带模型解析与不带模型解析主要在构造new Sheet(1, 2, LoanInfo.class)时候包含class。Class需要继承BaseRowModel暂时BaseRowModel没有任何内容,后面升级可能会增加一些默认的数据。

    3. 生成Excel

    每行数据是List无表头

            OutputStream out = new FileOutputStream("/Users/jipengfei/77.xlsx");
            try {
                ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX,false);
                //写第一个sheet, sheet1  数据全是List<String> 无模型映射关系
                Sheet sheet1 = new Sheet(1, 0);
                sheet1.setSheetName("第一个sheet");
                writer.write(getListString(), sheet1);
                writer.finish();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    

    每行数据是一个java模型有表头----表头层级为一

    生成Excel格式如下图:

    模型写法如下:

    public class ExcelPropertyIndexModel extends BaseRowModel {
    
        @ExcelProperty(value = "姓名" ,index = 0)
        private String name;
    
        @ExcelProperty(value = "年龄",index = 1)
        private String age;
    
        @ExcelProperty(value = "邮箱",index = 2)
        private String email;
    
        @ExcelProperty(value = "地址",index = 3)
        private String address;
    
        @ExcelProperty(value = "性别",index = 4)
        private String sax;
    
        @ExcelProperty(value = "高度",index = 5)
        private String heigh;
    
        @ExcelProperty(value = "备注",index = 6)
        private String last;
    }
    

    @ExcelProperty(value = “姓名”,index = 0) value是表头数据,默认会写在excel的表头位置,index代表第几列。

        @Test
        public void test1() throws FileNotFoundException {
            OutputStream out = new FileOutputStream("/Users/jipengfei/78.xlsx");
            try {
                ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);
                //写第一个sheet, sheet1  数据全是List<String> 无模型映射关系
                Sheet sheet1 = new Sheet(1, 0,ExcelPropertyIndexModel.class);
                writer.write(getData(), sheet1);
                writer.finish();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    

    每行数据是一个java模型有表头----表头层级为多层级

    生成Excel格式如下图:

    java模型写法如下:

    public class MultiLineHeadExcelModel extends BaseRowModel {
    
        @ExcelProperty(value = {"表头1","表头1","表头31"},index = 0)
        private String p1;
    
        @ExcelProperty(value = {"表头1","表头1","表头32"},index = 1)
        private String p2;
    
        @ExcelProperty(value = {"表头3","表头3","表头3"},index = 2)
        private int p3;
    
        @ExcelProperty(value = {"表头4","表头4","表头4"},index = 3)
        private long p4;
    
        @ExcelProperty(value = {"表头5","表头51","表头52"},index = 4)
        private String p5;
    
        @ExcelProperty(value = {"表头6","表头61","表头611"},index = 5)
        private String p6;
    
        @ExcelProperty(value = {"表头6","表头61","表头612"},index = 6)
        private String p7;
    
        @ExcelProperty(value = {"表头6","表头62","表头621"},index = 7)
        private String p8;
    
        @ExcelProperty(value = {"表头6","表头62","表头622"},index = 8)
        private String p9;
    }
    

    写Excel写法同上,只需将ExcelPropertyIndexModel.class改为MultiLineHeadExcelModel.class

    一个Excel多个sheet写法

        @Test
        public void test1() throws FileNotFoundException {
    
            OutputStream out = new FileOutputStream("/Users/jipengfei/77.xlsx");
            try {
                ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX,false);
                //写第一个sheet, sheet1  数据全是List<String> 无模型映射关系
                Sheet sheet1 = new Sheet(1, 0);
                sheet1.setSheetName("第一个sheet");
                writer.write(getListString(), sheet1);
    
                //写第二个sheet sheet2  模型上打有表头的注解,合并单元格
                Sheet sheet2 = new Sheet(2, 3, MultiLineHeadExcelModel.class, "第二个sheet", null);
                sheet2.setTableStyle(getTableStyle1());
                writer.write(getModeldatas(), sheet2);
    
                //写sheet3  模型上没有注解,表头数据动态传入
                List<List<String>> head = new ArrayList<List<String>>();
                List<String> headCoulumn1 = new ArrayList<String>();
                List<String> headCoulumn2 = new ArrayList<String>();
                List<String> headCoulumn3 = new ArrayList<String>();
                headCoulumn1.add("第一列");
                headCoulumn2.add("第二列");
                headCoulumn3.add("第三列");
                head.add(headCoulumn1);
                head.add(headCoulumn2);
                head.add(headCoulumn3);
                Sheet sheet3 = new Sheet(3, 1, NoAnnModel.class, "第三个sheet", head);
                writer.write(getNoAnnModels(), sheet3);
                writer.finish();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    

    一个sheet中有多个表格

        @Test
        public void test2() throws FileNotFoundException {
            OutputStream out = new FileOutputStream("/Users/jipengfei/77.xlsx");
            try {
                ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX,false);
    
                //写sheet1  数据全是List<String> 无模型映射关系
                Sheet sheet1 = new Sheet(1, 0);
                sheet1.setSheetName("第一个sheet");
                Table table1 = new Table(1);
                writer.write(getListString(), sheet1, table1);
                writer.write(getListString(), sheet1, table1);
    
                //写sheet2  模型上打有表头的注解
                Table table2 = new Table(2);
                table2.setTableStyle(getTableStyle1());
                table2.setClazz(MultiLineHeadExcelModel.class);
                writer.write(getModeldatas(), sheet1, table2);
    
                //写sheet3  模型上没有注解,表头数据动态传入,此情况下模型field顺序与excel现实顺序一致
                List<List<String>> head = new ArrayList<List<String>>();
                List<String> headCoulumn1 = new ArrayList<String>();
                List<String> headCoulumn2 = new ArrayList<String>();
                List<String> headCoulumn3 = new ArrayList<String>();
                headCoulumn1.add("第一列");
                headCoulumn2.add("第二列");
                headCoulumn3.add("第三列");
                head.add(headCoulumn1);
                head.add(headCoulumn2);
                head.add(headCoulumn3);
                Table table3 = new Table(3);
                table3.setHead(head);
                table3.setClazz(NoAnnModel.class);
                table3.setTableStyle(getTableStyle2());
                writer.write(getNoAnnModels(), sheet1, table3);
                writer.write(getNoAnnModels(), sheet1, table3);
    
                writer.finish();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    

    4. 测试数据分析

    从上面的性能测试可以看出easyexcel在解析耗时上比poiuserModel模式弱了一些。主要原因是我内部采用了反射做模型字段映射,中间我也加了cache,但感觉这点差距可以接受的。但在内存消耗上差别就比较明显了,easyexcel在后面文件再增大,内存消耗几乎不会增加了。但poi userModel就不一样了,简直就要爆掉了。想想一个excel解析200M,同时有20个人再用估计一台机器就挂了。

    5. 百万数据解析对比

    easyexcel解析百万数据内存图如下:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YVo5Q2gh-1631244928914)(https://www.itsleuth.cn/upload/2018/7/201807101724572018071110170464.png “easyexcel解析百万数据内存图”)]

    poi解析百万数据内存图如下:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9Ebaubd6-1631244928915)(https://www.itsleuth.cn/upload/2018/7/201807101732472018071110170462.png “poi解析百万数据内存图”)]

    从上面两图可以看出,easyexcel解析时内存消耗很少,最多消耗不到50M;POI解析过程中直接飘升到1.5G左右,系统内存耗尽,程序挂掉。

    GitHub地址:https://github.com/alibaba/easyexcel

    展开全文
  • 主要介绍了java解析excel文件的方法,这里整理相关的代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
  • Java解析Excel实例解析

    万次阅读 2017-03-09 10:32:55
    Java解析Excel实例解析

    最近有些配置APN的工作,需要将Excel中的信息,配置成Android apns-conf.xml中的样式。
    作为一个程序员,我怎么可能一行行的用眼睛看,然后用手去配置了!
    于是,我决定利用Apache POI的支持库,用java程序解析Excel表,
    然后按指定格式生成输出文件。

    这篇博客主要记录一下Java解析Excel的基本方法,结尾附上demo。


    首先附上Apache POI库的下载地址Apache POI - Download Release Artifacts
    选择合适的库后,会自动跳转到镜像地址。
    我的demo是基于poi-3.16-beta2写的,不过并没有使用什么高深接口,因此代码应该是通用的。

    导入依赖库后,主要的工作其实就是明白依赖库中定义的Excel对象了,这里盗一张图:

    如图所示:
    每一个Excel文件都将被解析成一个WorkBook对象;
    Excel的每一页都将被解析成一个Sheet对象;
    然后,Excel中的每一行都是一个Row对象,
    每一个单元格都是一个Cell对象。

    对这些基本概念有了一些基本了解后,就可以开始上实例了。

    如上图所示,为Excel中内容的基本格式,即一些APN需要的信息。
    为了方便我解析,我稍微修改了一些格式,将标题栏中每一项的首字母大写(与Java解析Excel无关)。

    Java入口函数如下:

    public class MainEntrance {
        public static void main(String[] args) {
            //由于Java解析Excel不可避免的与文件格式耦合
            //因此,我只能写一个特质化的工具,而不是写个模板
            ApnExcelParseTool excelParseTool = new ApnExcelParseTool();
    
            //传入源文件地址
            excelParseTool.setFilePath("/home/zhangjian/Desktop/all_apn_together.xlsx");
    
            try {
                //解析Excel得到Workbook对象
                Workbook workbook = excelParseTool.initWorkBook();
    
                //每一行具体数据,都将变成一个ApnModel
                List<ApnModel> outData = new ArrayList<>();
    
                if (workbook != null) {
                    //将workbook对象,解析成ApnModel
                    excelParseTool.parseWorkbook(workbook, outData);
                }
    
                if (outData.size() > 0) {
                    //将所有的ApnModel写入到输出文件中
                    new ApnWriteTool().write("/home/zhangjian/Desktop/apns-conf.xml", outData);
                }
            } catch (IOException e) {
                System.out.println(e.toString());
            }
        }
    }

    整个Java主函数的逻辑还是很简单的。


    现在我们看看核心类ApnExcelParseTool中的内容,首先看看获取Workbook相关的代码:

    class ApnExcelParseTool {
        private String mFilePath;
    
        //保存源文件内容
        void setFilePath(String filePath) {
            mFilePath = filePath;
        }
    
        private static final String SUFFIX_2003 = ".xls";
        private static final String SUFFIX_2007 = ".xlsx";
    
        Workbook initWorkBook() throws IOException {
            File file = new File(mFilePath);
            InputStream is = new FileInputStream(file);
    
            Workbook workbook = null;
            //根据后缀,得到不同的Workbook子类,即HSSFWorkbook或XSSFWorkbook
            if (mFilePath.endsWith(SUFFIX_2003)) {
                workbook = new HSSFWorkbook(is);
            } else if (mFilePath.endsWith(SUFFIX_2007)) {
                workbook = new XSSFWorkbook(is);
            }
    
            return workbook;
        }
    ....................

    得到Workbook后,就可以开始进一步解析了:

    .......................
        void parseWorkbook(Workbook workbook, List<ApnModel> apnModelList) {
            int numOfSheet = workbook.getNumberOfSheets();
    
            //依次解析每一个Sheet
            for (int i = 0; i < numOfSheet; ++i) {
                Sheet sheet = workbook.getSheetAt(i);
                parseSheet(sheet, apnModelList);
            }
        }
    
        //保存需要调用的ApnModel中的方法
        private List<Method> mUsedMethod;
    
        private void parseSheet(Sheet sheet, List<ApnModel> apnModelList) {
            Row row;
    
            int count = 0;
    
            //利用迭代器,取出每一个Row
            Iterator<Row> iterator = sheet.iterator();
            while(iterator.hasNext()) {
                row = iterator.next();
    
                //由于第一行是标题,因此这里单独处理
                if (count == 0) {
                    mUsedMethod = new ArrayList<>();
                    parseRowAndFindMethod(row);
                } else {
                    //其它行都在这里处理
                    parseRowAndFillData(row, apnModelList);
                }
    
                ++count;
            }
        }
    
        private void parseRowAndFindMethod(Row row) {
            //利用parseRow处理每一行,得到每个cell中的String
            List<String> rst = parseRow(row);
    
            String methodName;
            try {
                //根据String得到需要调用的ApnModel中的方法
                //由于自己在ApnModel中定义的方法均是类似setMcc、setMnc等
                //因此才在一开始,将标题栏中每一项大写
                for (String str : rst) {
                    methodName = "set" + str;
                    //反射拿到method
                    mUsedMethod.add(
                            ApnModel.class.getDeclaredMethod(methodName, String.class));
                }
            } catch (NoSuchMethodException e) {
                System.out.println(e.toString());
            }
    
        }
    
        //开始解析具体的数据
        private void parseRowAndFillData(Row row, List<ApnModel> apnModelList) {
            //同样利用parseRow得到具体每一行的数据
            List<String> rst = parseRow(row);
    
            ApnModel apnModel = new ApnModel();
    
            //这里主要debug一下,避免由于Excel的格式可能不太对
            //使得每一行的数据解析地不太对
            if (mUsedMethod.size() != rst.size()) {
                System.out.println("WTF, size not right");
            } else {
                //利用反射,将数据填充到具体的ApnModel
                try {
                    for (int i = 0; i < mUsedMethod.size(); ++i) {
                        mUsedMethod.get(i).invoke(apnModel, rst.get(i));
                    }
    
                    //保存到输出结果中
                    apnModelList.add(apnModel);
                } catch (Exception e) {
                    System.out.println(e.toString());
                }
            }
        }
    
        //这里是解析每一行的代码
        private List<String> parseRow(Row row) {
            List<String> rst = new ArrayList<>();
    
            Cell cell;
    
            //利用迭代器得到每一个cell
            Iterator<Cell> iterator = row.iterator();
            while (iterator.hasNext()) {
                cell = iterator.next();
    
                //定义每一个cell的数据类型
                cell.setCellType(CellType.STRING);
    
                //取出cell中的value
                rst.add(cell.getStringCellValue());
            }
    
            return rst;
        }
    .................

    以上就是Java解析Excel范例的核心代码了。

    之后的工作就是将ApnModel中保存的数据,按照需要的格式写入到输出文件了。
    这部分代码比较粗糙,也与主题无关,就不直接贴到博客上了。

    最后的输出结果类似于。与原生的格式一致了:

    这里唯一要注意的是,要保证Excel的格式正确。
    单元格的内容可以是空白的,因此要保证Excel中仅有数据占有了实际的内容。

    如上图所示,数据部分可以空白,但非数据的红色部分就不要有内容了。

    最后,demo地址如下:
    https://github.com/ZhangJianIsAStark/ExcelParseDemo
    这里我只上传了源代码,还需要自己配置Apache POI jar包。

    展开全文
  • POI java解析EXCEL

    2012-09-04 12:30:55
    POI java解析EXCEL框架 jar

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 30,729
精华内容 12,291
关键字:

java解析excel

java 订阅