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
  • 相关阅读:
    算法分析(3)——冒泡排序真的慢吗?
    算法分析(2)——大O和大Θ
    算法分析(1)——数据的影响和函数的增长
    递归的逻辑(5)——米诺斯的迷宫
    递归的逻辑(4)——递归与分形
    李洪强和你一起学习前端之(9)规避脱标,CSS可见性,滑动门案例
    iOS应用管理(优化)
    iOS开发-应用管理
    iOS开发-Tom猫
    iOS 10.3.3 更新背后的故事
  • 原文地址:https://www.cnblogs.com/xichji/p/11679793.html
Copyright © 2011-2022 走看看