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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM