zoukankan      html  css  js  c++  java
  • JAVA使用easyexcel操作Excel

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。           
                  
                        本文链接:https://blog.csdn.net/jianggujin/article/details/80200400
                   
               
                       
                                                       
                                           
                       
                       
                                                之前写过一篇《JAVA操作Excel》,介绍了jxl和poi读写Excel的实现,今天为大家介绍一下使用easyexcel对Excel进行读写,项目主页地址:https://github.com/alibaba/easyexcel
    作者对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,首先我们需要添加maven依赖:
     
    <dependency>
       <groupId>com.alibaba</groupId>
       <artifactId>easyexcel</artifactId>
       <version>1.0.1</version>
    </dependency>12345
    首先,我们先来看看如何写Excel,写入Excel,我们可以通过com.alibaba.excel.ExcelWriter类实现,下面我们来看一下最简单的无表头的实现
     
    package test;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.util.ArrayList;
    import java.util.List;
    import org.junit.Test;
    import com.alibaba.excel.ExcelWriter;
    import com.alibaba.excel.metadata.Sheet;
    import com.alibaba.excel.support.ExcelTypeEnum;
    public class ExcelWriteTest {
       /**
        * 每行数据是List<String>无表头
        *
        * @throws IOException
        */
       @Test
       public void writeWithoutHead() throws IOException {
          try (OutputStream out = new FileOutputStream("withoutHead.xlsx");) {
             ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX, false);
             Sheet sheet1 = new Sheet(1, 0);
             sheet1.setSheetName("sheet1");
             List<List<String>> data = new ArrayList<>();
             for (int i = 0; i < 100; i++) {
                List<String> item = new ArrayList<>();
                item.add("item0" + i);
                item.add("item1" + i);
                item.add("item2" + i);
                data.add(item);
             }
             writer.write0(data, sheet1);
             writer.finish();
          }
       }
    }12345678910111213141516171819202122232425262728293031323334353637383940
    生成的Excel样式如下:

    很多时候,我们在生成Excel的时候都是需要添加表头的,使用easyexcel可以很容易的实现,我们可以对上面的例子进行简单的改造,为其添加表头
     
    package test;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.util.ArrayList;
    import java.util.List;
    import org.junit.Test;
    import com.alibaba.excel.ExcelWriter;
    import com.alibaba.excel.metadata.Sheet;
    import com.alibaba.excel.metadata.Table;
    import com.alibaba.excel.support.ExcelTypeEnum;
    public class ExcelWriteTest {
       @Test
       public void writeWithoutHead() throws IOException {
          try (OutputStream out = new FileOutputStream("withHead.xlsx");) {
             ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);
             Sheet sheet1 = new Sheet(1, 0);
             sheet1.setSheetName("sheet1");
             List<List<String>> data = new ArrayList<>();
             for (int i = 0; i < 100; i++) {
                List<String> item = new ArrayList<>();
                item.add("item0" + i);
                item.add("item1" + i);
                item.add("item2" + i);
                data.add(item);
             }
             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 table = new Table(1);
             table.setHead(head);
             writer.write0(data, sheet1, table);
             writer.finish();
          }
       }
    }123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
    效果如下:
     
    除了上面添加表头的方式,我们还可以使用实体类,为其添加com.alibaba.excel.annotation.ExcelProperty注解来生成表头,实体类数据作为Excel数据
     
    package test;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.util.ArrayList;
    import java.util.List;
    import org.junit.Test;
    import com.alibaba.excel.ExcelWriter;
    import com.alibaba.excel.annotation.ExcelProperty;
    import com.alibaba.excel.metadata.BaseRowModel;
    import com.alibaba.excel.metadata.Sheet;
    import com.alibaba.excel.metadata.Table;
    import com.alibaba.excel.support.ExcelTypeEnum;
    public class ExcelWriteTest {
       @Test
       public void writeWithHead() throws IOException {
          try (OutputStream out = new FileOutputStream("withHead.xlsx");) {
             ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);
             Sheet sheet1 = new Sheet(1, 0, ExcelPropertyIndexModel.class);
             sheet1.setSheetName("sheet1");
             List<ExcelPropertyIndexModel> data = new ArrayList<>();
             for (int i = 0; i < 100; i++) {
                ExcelPropertyIndexModel item = new ExcelPropertyIndexModel();
                item.name = "name" + i;
                item.age = "age" + i;
                item.email = "email" + i;
                item.address = "address" + i;
                item.sax = "sax" + i;
                item.heigh = "heigh" + i;
                item.last = "last" + i;
                data.add(item);
             }
             writer.write(data, sheet1);
             writer.finish();
          }
       }
       public static 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;
          public String getName() {
             return name;
          }
          public void setName(String name) {
             this.name = name;
          }
          public String getAge() {
             return age;
          }
          public void setAge(String age) {
             this.age = age;
          }
          public String getEmail() {
             return email;
          }
          public void setEmail(String email) {
             this.email = email;
          }
          public String getAddress() {
             return address;
          }
          public void setAddress(String address) {
             this.address = address;
          }
          public String getSax() {
             return sax;
          }
          public void setSax(String sax) {
             this.sax = sax;
          }
          public String getHeigh() {
             return heigh;
          }
          public void setHeigh(String heigh) {
             this.heigh = heigh;
          }
          public String getLast() {
             return last;
          }
          public void setLast(String last) {
             this.last = last;
          }
       }
    }123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
    效果如下:

    如果单行表头表头还不满足需求,没关系,还可以使用多行复杂的表头
     
    package test;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.util.ArrayList;
    import java.util.List;
    import org.junit.Test;
    import com.alibaba.excel.ExcelWriter;
    import com.alibaba.excel.annotation.ExcelProperty;
    import com.alibaba.excel.metadata.BaseRowModel;
    import com.alibaba.excel.metadata.Sheet;
    import com.alibaba.excel.metadata.Table;
    import com.alibaba.excel.support.ExcelTypeEnum;
    public class ExcelWriteTest {
       @Test
       public void writeWithMultiHead() throws IOException {
          try (OutputStream out = new FileOutputStream("withMultiHead.xlsx");) {
             ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);
             Sheet sheet1 = new Sheet(1, 0, MultiLineHeadExcelModel.class);
             sheet1.setSheetName("sheet1");
             List<MultiLineHeadExcelModel> data = new ArrayList<>();
             for (int i = 0; i < 100; i++) {
                MultiLineHeadExcelModel item = new MultiLineHeadExcelModel();
                item.p1 = "p1" + i;
                item.p2 = "p2" + i;
                item.p3 = "p3" + i;
                item.p4 = "p4" + i;
                item.p5 = "p5" + i;
                item.p6 = "p6" + i;
                item.p7 = "p7" + i;
                item.p8 = "p8" + i;
                item.p9 = "p9" + i;
                data.add(item);
             }
             writer.write(data, sheet1);
             writer.finish();
          }
       }
       public static 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 String p3;
          @ExcelProperty(value = { "表头4", "表头4", "表头4" }, index = 3)
          private String 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;
          public String getP1() {
             return p1;
          }
          public void setP1(String p1) {
             this.p1 = p1;
          }
          public String getP2() {
             return p2;
          }
          public void setP2(String p2) {
             this.p2 = p2;
          }
          public String getP3() {
             return p3;
          }
          public void setP3(String p3) {
             this.p3 = p3;
          }
          public String getP4() {
             return p4;
          }
          public void setP4(String p4) {
             this.p4 = p4;
          }
          public String getP5() {
             return p5;
          }
          public void setP5(String p5) {
             this.p5 = p5;
          }
          public String getP6() {
             return p6;
          }
          public void setP6(String p6) {
             this.p6 = p6;
          }
          public String getP7() {
             return p7;
          }
          public void setP7(String p7) {
             this.p7 = p7;
          }
          public String getP8() {
             return p8;
          }
          public void setP8(String p8) {
             this.p8 = p8;
          }
          public String getP9() {
             return p9;
          }
          public void setP9(String p9) {
             this.p9 = p9;
          }
       }
    }123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
    效果如下:

    怎么样,这些已经基本满足我们的日常需求了,easyexcel不仅支持上述几种形式,还支持在一个sheet中添加多个表
     
    package test;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.util.ArrayList;
    import java.util.List;
    import org.junit.Test;
    import com.alibaba.excel.ExcelWriter;
    import com.alibaba.excel.annotation.ExcelProperty;
    import com.alibaba.excel.metadata.BaseRowModel;
    import com.alibaba.excel.metadata.Sheet;
    import com.alibaba.excel.metadata.Table;
    import com.alibaba.excel.support.ExcelTypeEnum;
    public class ExcelWriteTest {
       @Test
       public void writeWithMultiTable() throws IOException {
          try (OutputStream out = new FileOutputStream("withMultiTable.xlsx");) {
             ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);
             Sheet sheet1 = new Sheet(1, 0);
             sheet1.setSheetName("sheet1");
             // 数据全是List<String> 无模型映射关系
             Table table1 = new Table(1);
             List<List<String>> data1 = new ArrayList<>();
             for (int i = 0; i < 5; i++) {
                List<String> item = new ArrayList<>();
                item.add("item0" + i);
                item.add("item1" + i);
                item.add("item2" + i);
                data1.add(item);
             }
             writer.write0(data1, sheet1, table1);
             // 模型上有表头的注解
             Table table2 = new Table(2);
             table2.setClazz(MultiLineHeadExcelModel.class);
             List<MultiLineHeadExcelModel> data2 = new ArrayList<>();
             for (int i = 0; i < 5; i++) {
                MultiLineHeadExcelModel item = new MultiLineHeadExcelModel();
                item.p1 = "p1" + i;
                item.p2 = "p2" + i;
                item.p3 = "p3" + i;
                item.p4 = "p4" + i;
                item.p5 = "p5" + i;
                item.p6 = "p6" + i;
                item.p7 = "p7" + i;
                item.p8 = "p8" + i;
                item.p9 = "p9" + i;
                data2.add(item);
             }
             writer.write(data2, sheet1, table2);
             // 模型上没有注解,表头数据动态传入,此情况下模型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);
             writer.write0(data1, sheet1, table3);
             writer.finish();
          }
       }
       public static 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 String p3;
          @ExcelProperty(value = { "表头4", "表头4", "表头4" }, index = 3)
          private String 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;
          public String getP1() {
             return p1;
          }
          public void setP1(String p1) {
             this.p1 = p1;
          }
          public String getP2() {
             return p2;
          }
          public void setP2(String p2) {
             this.p2 = p2;
          }
          public String getP3() {
             return p3;
          }
          public void setP3(String p3) {
             this.p3 = p3;
          }
          public String getP4() {
             return p4;
          }
          public void setP4(String p4) {
             this.p4 = p4;
          }
          public String getP5() {
             return p5;
          }
          public void setP5(String p5) {
             this.p5 = p5;
          }
          public String getP6() {
             return p6;
          }
          public void setP6(String p6) {
             this.p6 = p6;
          }
          public String getP7() {
             return p7;
          }
          public void setP7(String p7) {
             this.p7 = p7;
          }
          public String getP8() {
             return p8;
          }
          public void setP8(String p8) {
             this.p8 = p8;
          }
          public String getP9() {
             return p9;
          }
          public void setP9(String p9) {
             this.p9 = p9;
          }
       }
    }123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
    效果如下:

    如果表头的样式不满足我们的需求,需要调整,我们可以使用com.alibaba.excel.metadata.TableStyle定义我们需要的样式,然后调用table对象的setTableStyle方法进行设置。
    好了,到这里写入excel就基本介绍完了,下面我们就来看看如何读取excel,实际上现在的这个版本(1.0.1)在读取的时候是有BUG的,读取03版的.xls格式的excel正常,但是读取07版的.xlsx版的excel就会出异常,原因是在解析的时候sheet临时文件路径拼装有误,下面是我针对这个版本修复后的实现,大家可以替换掉原包中的实现
     
    package com.alibaba.excel.read;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Locale;
    import javax.xml.parsers.ParserConfigurationException;
    import com.alibaba.excel.read.v07.RowHandler;
    import com.alibaba.excel.read.v07.XmlParserFactory;
    import com.alibaba.excel.read.v07.XMLTempFile;
    import com.alibaba.excel.read.context.AnalysisContext;
    import com.alibaba.excel.read.exception.ExcelAnalysisException;
    import com.alibaba.excel.metadata.Sheet;
    import com.alibaba.excel.util.FileUtil;
    import org.apache.poi.xssf.model.SharedStringsTable;
    import org.apache.xmlbeans.XmlException;
    import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook;
    import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbookPr;
    import org.openxmlformats.schemas.spreadsheetml.x2006.main.WorkbookDocument;
    import org.xml.sax.Attributes;
    import org.xml.sax.ContentHandler;
    import org.xml.sax.SAXException;
    import org.xml.sax.helpers.DefaultHandler;
    public class SaxAnalyserV07 extends BaseSaxAnalyser {
        private SharedStringsTable sharedStringsTable;
        private List<String> sharedStringList = new LinkedList<String>();
        private List<SheetSource> sheetSourceList = new ArrayList<SheetSource>();
        private boolean use1904WindowDate = false;
        private final String path;
        private File tmpFile;
        private String workBookXMLFilePath;
        private String sharedStringXMLFilePath;
        public SaxAnalyserV07(AnalysisContext analysisContext) throws Exception {
            this.analysisContext = analysisContext;
            this.path = XMLTempFile.createPath();
            this.tmpFile = new File(XMLTempFile.getTmpFilePath(path));
            this.workBookXMLFilePath = XMLTempFile.getWorkBookFilePath(path);
            this.sharedStringXMLFilePath = XMLTempFile.getSharedStringFilePath(path);
            start();
        }
        @Override
        protected void execute() {
            try {
                Sheet sheet = analysisContext.getCurrentSheet();
                if (!isAnalysisAllSheets(sheet)) {
                    if (this.sheetSourceList.size() < sheet.getSheetNo() || sheet.getSheetNo() == 0) {
                        return;
                    }
                    InputStream sheetInputStream = this.sheetSourceList.get(sheet.getSheetNo() - 1).getInputStream();
                    parseXmlSource(sheetInputStream);
                    return;
                }
                int i = 0;
                for (SheetSource sheetSource : this.sheetSourceList) {
                    i++;
                    this.analysisContext.setCurrentSheet(new Sheet(i));
                    parseXmlSource(sheetSource.getInputStream());
                }
            } catch (Exception e) {
                stop();
                throw new ExcelAnalysisException(e);
            } finally {
            }
        }
        private boolean isAnalysisAllSheets(Sheet sheet) {
            if (sheet == null) {
                return true;
            }
            if (sheet.getSheetNo() < 0) {
                return true;
            }
            return false;
        }
        public void stop() {
            FileUtil.deletefile(path);
        }
        private void parseXmlSource(InputStream inputStream) {
            try {
                ContentHandler handler = new RowHandler(this, this.sharedStringsTable, this.analysisContext,
                    sharedStringList);
                XmlParserFactory.parse(inputStream, handler);
                inputStream.close();
            } catch (Exception e) {
                try {
                    inputStream.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
                throw new ExcelAnalysisException(e);
            }
        }
        public List<Sheet> getSheets() {
            List<Sheet> sheets = new ArrayList<Sheet>();
            try {
                int i = 1;
                for (SheetSource sheetSource : this.sheetSourceList) {
                    Sheet sheet = new Sheet(i, 0);
                    sheet.setSheetName(sheetSource.getSheetName());
                    i++;
                    sheets.add(sheet);
                }
            } catch (Exception e) {
                stop();
                throw new ExcelAnalysisException(e);
            } finally {
            }
            return sheets;
        }
        private void start() throws IOException, XmlException, ParserConfigurationException, SAXException {
            createTmpFile();
            unZipTempFile();
            initSharedStringsTable();
            initUse1904WindowDate();
            initSheetSourceList();
        }
        private void createTmpFile() throws FileNotFoundException {
            FileUtil.writeFile(tmpFile, analysisContext.getInputStream());
        }
        private void unZipTempFile() throws IOException {
            FileUtil.doUnZip(path, tmpFile);
        }
        private void initSheetSourceList() throws IOException, ParserConfigurationException, SAXException {
            this.sheetSourceList = new ArrayList<SheetSource>();
            InputStream workbookXml = new FileInputStream(this.workBookXMLFilePath);
            XmlParserFactory.parse(workbookXml, new DefaultHandler() {
                @Override
                public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException {
                    if (qName.toLowerCase(Locale.US).equals("sheet")) {
                        String name = null;
                        int id = 0;
                        for (int i = 0; i < attrs.getLength(); i++) {
                            if (attrs.getLocalName(i).toLowerCase(Locale.US).equals("name")) {
                                name = attrs.getValue(i);
                            }/** else if (attrs.getLocalName(i).toLowerCase(Locale.US).equals("r:id")) {
                                id = Integer.parseInt(attrs.getValue(i).replaceAll("rId", ""));
                                try {
                                    InputStream inputStream = new FileInputStream(XMLTempFile.getSheetFilePath(path, id));
                                    sheetSourceList.add(new SheetSource(id, name, inputStream));
                                } catch (FileNotFoundException e) {
                                    e.printStackTrace();
                                }
                            } **/
                            //应该使用sheetId属性
                            else if (attrs.getLocalName(i).toLowerCase(Locale.US).equals("sheetid")) {
                                id = Integer.parseInt(attrs.getValue(i));
                                try {
                                    InputStream inputStream = new FileInputStream(XMLTempFile.getSheetFilePath(path, id));
                                    sheetSourceList.add(new SheetSource(id, name, inputStream));
                                } catch (FileNotFoundException e) {
                                    e.printStackTrace();
                                }
                           }
                        }
                    }
                }
            });
            workbookXml.close();
            // 排序后是倒序,不符合实际要求
            // Collections.sort(sheetSourceList);
            Collections.sort(sheetSourceList, new Comparator<SheetSource>() {
               @Override
               public int compare(SheetSource o1, SheetSource o2) {
                  return o1.id - o2.id;
               }
            });
        }
        private void initUse1904WindowDate() throws IOException, XmlException {
            InputStream workbookXml = new FileInputStream(workBookXMLFilePath);
            WorkbookDocument ctWorkbook = WorkbookDocument.Factory.parse(workbookXml);
            CTWorkbook wb = ctWorkbook.getWorkbook();
            CTWorkbookPr prefix = wb.getWorkbookPr();
            if (prefix != null) {
                this.use1904WindowDate = prefix.getDate1904();
            }
            this.analysisContext.setUse1904WindowDate(use1904WindowDate);
            workbookXml.close();
        }
        private void initSharedStringsTable() throws IOException, ParserConfigurationException, SAXException {
            //因为sharedStrings.xml文件不一定存在,所以在处理之前增加判断
            File sharedStringXMLFile = new File(this.sharedStringXMLFilePath);
            if (!sharedStringXMLFile.exists()) {
                return;
            }
            InputStream inputStream = new FileInputStream(this.sharedStringXMLFilePath);
            //this.sharedStringsTable = new SharedStringsTable();
            //this.sharedStringsTable.readFrom(inputStream);
            XmlParserFactory.parse(inputStream, new DefaultHandler() {
                @Override
                public void characters(char[] ch, int start, int length) {
                    sharedStringList.add(new String(ch, start, length));
                }
            });
            inputStream.close();
        }
        private class SheetSource implements Comparable<SheetSource> {
            private int id;
            private String sheetName;
            private InputStream inputStream;
            public SheetSource(int id, String sheetName, InputStream inputStream) {
                this.id = id;
                this.sheetName = sheetName;
                this.inputStream = inputStream;
            }
            public String getSheetName() {
                return sheetName;
            }
            public void setSheetName(String sheetName) {
                this.sheetName = sheetName;
            }
            public InputStream getInputStream() {
                return inputStream;
            }
            public void setInputStream(InputStream inputStream) {
                this.inputStream = inputStream;
            }
            public int getId() {
                return id;
            }
            public void setId(int id) {
                this.id = id;
            }
            public int compareTo(SheetSource o) {
                if (o.id == this.id) {
                    return 0;
                } else if (o.id > this.id) {
                    return 1;
                } else {
                    return -1;
                }
            }
        }
    }123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
    另外,使用easyexcel读取excel的时候需要设置excel的版本,但是有些时候我们无法预知excel的版本,所以个人感觉这样不是太好,所以模仿poi写了一个用于获取com.alibaba.excel.ExcelReader对象的工具类
    package com.alibaba.excel.read;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.PushbackInputStream;
    import org.apache.poi.EmptyFileException;
    import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
    import org.apache.poi.poifs.filesystem.DocumentFactoryHelper;
    import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
    import org.apache.poi.util.IOUtils;
    import com.alibaba.excel.ExcelReader;
    import com.alibaba.excel.read.context.AnalysisContext;
    import com.alibaba.excel.read.event.AnalysisEventListener;
    import com.alibaba.excel.support.ExcelTypeEnum;
    public class ExcelReaderFactory {
       /**
        * @param in
        *           文件输入流
        * @param customContent
        *           自定义模型可以在
        *           {@link AnalysisEventListener#invoke(Object, AnalysisContext) }
        *           AnalysisContext中获取用于监听者回调使用
        * @param eventListener
        *           用户监听
        * @throws IOException
        * @throws EmptyFileException
        * @throws InvalidFormatException
        */
       public static ExcelReader getExcelReader(InputStream in, Object customContent,
             AnalysisEventListener<?> eventListener) throws EmptyFileException, IOException, InvalidFormatException {
          // 如果输入流不支持mark/reset,需要对其进行包裹
          if (!in.markSupported()) {
             in = new PushbackInputStream(in, 8);
          }
          // 确保至少有一些数据
          byte[] header8 = IOUtils.peekFirst8Bytes(in);
          ExcelTypeEnum excelTypeEnum = null;
          if (NPOIFSFileSystem.hasPOIFSHeader(header8)) {
             excelTypeEnum = ExcelTypeEnum.XLS;
          }
          if (DocumentFactoryHelper.hasOOXMLHeader(in)) {
             excelTypeEnum = ExcelTypeEnum.XLSX;
          }
          if (excelTypeEnum != null) {
             return new ExcelReader(in, excelTypeEnum, customContent, eventListener);
          }
          throw new InvalidFormatException("Your InputStream was neither an OLE2 stream, nor an OOXML stream");
       }
       /**
        * @param in
        *           文件输入流
        * @param customContent
        *           自定义模型可以在
        *           {@link AnalysisEventListener#invoke(Object, AnalysisContext) }
        *           AnalysisContext中获取用于监听者回调使用
        * @param eventListener
        *           用户监听
        * @param trim
        *           是否对解析的String做trim()默认true,用于防止 excel中空格引起的装换报错。
        * @throws IOException
        * @throws EmptyFileException
        * @throws InvalidFormatException
        */
       public static ExcelReader getExcelReader(InputStream in, Object customContent,
             AnalysisEventListener<?> eventListener, boolean trim)
             throws EmptyFileException, IOException, InvalidFormatException {
          // 如果输入流不支持mark/reset,需要对其进行包裹
          if (!in.markSupported()) {
             in = new PushbackInputStream(in, 8);
          }
          // 确保至少有一些数据
          byte[] header8 = IOUtils.peekFirst8Bytes(in);
          ExcelTypeEnum excelTypeEnum = null;
          if (NPOIFSFileSystem.hasPOIFSHeader(header8)) {
             excelTypeEnum = ExcelTypeEnum.XLS;
          }
          if (DocumentFactoryHelper.hasOOXMLHeader(in)) {
             excelTypeEnum = ExcelTypeEnum.XLSX;
          }
          if (excelTypeEnum != null) {
             return new ExcelReader(in, excelTypeEnum, customContent, eventListener, trim);
          }
          throw new InvalidFormatException("Your InputStream was neither an OLE2 stream, nor an OOXML stream");
       }
    }1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
    下面我们就来写一个简单的读取Excel的示例:
     
    package test;
    import java.io.FileInputStream;
    import java.io.InputStream;
    import java.util.List;
    import org.junit.Test;
    import com.alibaba.excel.ExcelReader;
    import com.alibaba.excel.annotation.ExcelProperty;
    import com.alibaba.excel.metadata.BaseRowModel;
    import com.alibaba.excel.metadata.Sheet;
    import com.alibaba.excel.read.ExcelReaderFactory;
    import com.alibaba.excel.read.context.AnalysisContext;
    import com.alibaba.excel.read.event.AnalysisEventListener;
    public class ExcelReadTest {
       @Test
       public void read() throws Exception {
          try (InputStream in = new FileInputStream("withoutHead.xlsx");) {
             AnalysisEventListener<List<String>> listener = new AnalysisEventListener<List<String>>() {
                @Override
                public void invoke(List<String> object, AnalysisContext context) {
                   System.err.println("Row:" + context.getCurrentRowNum() + " Data:" + object);
                }
                @Override
                public void doAfterAllAnalysed(AnalysisContext context) {
                   System.err.println("doAfterAllAnalysed...");
                }
             };
             ExcelReader excelReader = ExcelReaderFactory.getExcelReader(in, null, listener);
             excelReader.read();
          }
       }
    }12345678910111213141516171819202122232425262728293031323334353637
    正如写入Excel的时候可以使用数据模型一样,在读取Excel的时候也可以直接将数据映射为模型对象,区别在于要使用ExcelReader #read的重载方法。
     
    package test;
    import java.io.FileInputStream;
    import java.io.InputStream;
    import java.util.List;
    import org.junit.Test;
    import com.alibaba.excel.ExcelReader;
    import com.alibaba.excel.annotation.ExcelProperty;
    import com.alibaba.excel.metadata.BaseRowModel;
    import com.alibaba.excel.metadata.Sheet;
    import com.alibaba.excel.read.ExcelReaderFactory;
    import com.alibaba.excel.read.context.AnalysisContext;
    import com.alibaba.excel.read.event.AnalysisEventListener;
    public class ExcelReadTest {
       @Test
       public void read() throws Exception {
          try (InputStream in = new FileInputStream("withHead.xlsx");) {
             AnalysisEventListener<ExcelPropertyIndexModel> listener = new AnalysisEventListener<ExcelPropertyIndexModel>() {
                @Override
                public void invoke(ExcelPropertyIndexModel object, AnalysisContext context) {
                   System.err.println("Row:" + context.getCurrentRowNum() + " Data:" + object);
                }
                @Override
                public void doAfterAllAnalysed(AnalysisContext context) {
                   System.err.println("doAfterAllAnalysed...");
                }
             };
             ExcelReader excelReader = ExcelReaderFactory.getExcelReader(in, null, listener);
             // 第二个参数为表头行数,按照实际设置
             excelReader.read(new Sheet(1, 1, ExcelPropertyIndexModel.class));
          }
       }
       public static 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;
          public String getName() {
             return name;
          }
          public void setName(String name) {
             this.name = name;
          }
          public String getAge() {
             return age;
          }
          public void setAge(String age) {
             this.age = age;
          }
          public String getEmail() {
             return email;
          }
          public void setEmail(String email) {
             this.email = email;
          }
          public String getAddress() {
             return address;
          }
          public void setAddress(String address) {
             this.address = address;
          }
          public String getSax() {
             return sax;
          }
          public void setSax(String sax) {
             this.sax = sax;
          }
          public String getHeigh() {
             return heigh;
          }
          public void setHeigh(String heigh) {
             this.heigh = heigh;
          }
          public String getLast() {
             return last;
          }
          public void setLast(String last) {
             this.last = last;
          }
          @Override
          public String toString() {
             return "ExcelPropertyIndexModel [name=" + name + ", age=" + age + ", email=" + email + ", address=" + address
                   + ", sax=" + sax + ", heigh=" + heigh + ", last=" + last + "]";
          }
       }
    }123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
    以上就是关于easyexcel的使用方法介绍,如有疑问,欢迎交流指正。
    ————————————————
    版权声明:本文为CSDN博主「蒋固金」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/jianggujin/article/details/80200400
  • 相关阅读:
    那些离不开的 Chrome 扩展插件
    Spring Boot 实战 —— 入门
    Maven 学习笔记
    Linux lvm 分区知识笔记
    Linux 双向 SSH 免密登录
    CentOS Yum 源搭建
    Ubuntu 系统学习
    iOS 测试三方 KIF 的那些事
    Swift 网络请求数据与解析
    iOS Plist 文件的 增 删 改
  • 原文地址:https://www.cnblogs.com/xichji/p/11679793.html
Copyright © 2011-2022 走看看