java Excel導入導出,基於XML的實現,easy-excel使用


項目地址:http://git.oschina.net/lis1314/easy-excel

使用easy-excel 完成Excel導入導出功能

下面有如下的幾個模型

學生模型,圖書模型,作者模型

//學生模型 public class StudentModel { /** ID */ protected String id; /** 創建時間 */ protected Date createTime; /** 姓名 */ private String name; /** 年齡 */ private Integer age; /** 學號 */ private String studentNo; /** 創建人 */ private String createUser; /** 創建人ID */ private String createUserId; /** 狀態 */ private Integer status; /** 圖書信息 */ private BookModel book; //略 getter setter... } //圖書模型 public class BookModel { /** 圖書名稱 */ private String bookName; /** 作者信息 */ private AuthorModel author; //略 getter setter... } //作者模型 public class AuthorModel { /** 作者姓名 */ private String authorName; //略 getter setter... }

有如下的Excel文件格式,需要映射成學生實體類

那么使用easy-excel 如何導入呢?

前兩行是屬於不規則的數據,從標題行以后才是規則的數據,也就是從規則數據之后才能正常轉換成JavaBean。

下面使用easy-excel進行導入

1、下載easy-excel,引入到自己的工程,它是一個jar的maven工程,直接添加依賴即可

http://git.oschina.net/lis1314/easy-excel

2、具體實現代碼,首先編寫配置文件:excel-config.xml

<excels> <excel id="student" class="org.easy.excel.test.model.StudentModel"> <field name="id" title="ID"/> <field name="name" title="學生姓名"/> <field name="age" title="年齡" isNull="false" regex="^[1-9]\d*$" regexErrMsg="必須是數字"/> <field name="studentNo" title="學號" isNull="false" /> <field name="createTime" title="創建時間" pattern="yyyy-MM-dd,yyyy/MM/dd"/> <field name="status" title="狀態" format="1:正常,0:禁用,-1:無效" /> <field name="createUser" title="創建人"/> <!-- 復雜對象 --> <field name="book.bookName" title="圖書名稱" /> <field name="book.author.authorName" title="作者名稱"/> </excel> </excels>

解釋,每個excel表示一種Excel文件到JavaBean的映射規則,該規則可以是導入和導出

標簽解釋

配置了一個id為student的映射,要映射對應的JavaBean實體為 StudentModel

<excel id="student" class="org.easy.excel.test.model.StudentModel">

excel文件中標題為ID的列,把它的值映射到 StudentModel .id屬性上

<field name="id" title="ID"/>

isNull屬性,表示在excel文件中標題為【年齡】的單元格的值不能為空,並且符合正則【 regex 】,當正則校驗沒有通過時,會提示【xxx行,[ 年齡 ]必須是數字,如果為空同理,xxx行[年齡]不能為空】

<field name="age" title="年齡" isNull="false" regex="^[1-9]\d*$" regexErrMsg="必須是數字"/>

pattern:不做過多解釋,SimpleDateFormat(pattern),導入數據時字符串的值如何轉換成日期

支持多種映射pattern,使用【英文逗號】進行分割

<field name="createTime" title="創建時間" pattern="yyyy-MM-dd,yyyy/MM/dd"/>

format屬性,觀察上面的excel文件結構會發現狀態列是中文,那么導入時,可能javaBean中並不是中文,而是數字或其他,那么如何把它轉換成數字呢?format就是做這個事情的。導入時它會以【,分割:前面的作為導入時使用的值,:后面的作為導出時使用的值】:后面值進行逆推,導出時同理。思考一個問題?如果這個值不確定如何解決,或者這個值需要到數據庫校驗?比如是個城市地址,這個時候是需要查詢數據庫進行比對的,如果地址不存在則拋出錯誤提示信息的,就說這么多,easy-excel已經做好了,支持自定義的轉換器可以解決。

<field name="status" title="狀態" format="1:正常,0:禁用,-1:無效" />

把excel文件標題為【圖書名稱】的值映射到 StudentModel 類中的book類中的bookName屬性上

<field name="book.bookName" title="圖書名稱" />

-----------不每條配置都解釋了,明白標簽的作用我想大家能看懂。下面展示Java代碼

public class ImportTest { public static void main(String[] args) throws Exception { //准備excel文件流 InputStream excelStream = new FileInputStream("C:/Users/Administrator/Desktop/stu.xlsx"); //創建excel上下文實例,它的構成需要配置文件的路徑 ExcelContext context = new ExcelContext("excel-config.xml"); //按照xml配置中id為student的配置形式讀取excel文件,並轉換成StudentModel //這里的第二個參數是值,標題是第幾行開始,之前也說了標題之前的數據並不是規則的數據 ExcelImportResult result = context.readExcel("student", 2,excelStream); //打印導入結果,查看標題之前不規則的數據 List<List<Object>> header = result.getHeader(); System.out.println(header.get(0)); System.out.println(header.get(1)); //查看學生集合導入結果 List<StudentModel> students = result.getListBean(); for(StudentModel stu:students){ System.out.println(stu); } } }

運行結果:

[共導出【10】條數據] [本次批次號為:XXX] StudentModel [id=1, createTime=Sat Jun 18 00:00:00 GMT+08:00 2016, name=張三0, age=20, studentNo=Stu_0, createUser=王五0, createUserId=null, status=1, book=BookModel [bookName=Thinking in java, author=AuthorModel [authorName=Bruce Eckel]]] StudentModel [id=2, createTime=Sat Jun 18 00:00:00 GMT+08:00 2016, name=張三1, age=21, studentNo=Stu_1, createUser=王五1, createUserId=null, status=0, book=null] StudentModel [id=3, createTime=Sat Jun 18 00:00:00 GMT+08:00 2016, name=張三2, age=22, studentNo=Stu_2, createUser=王五2, createUserId=null, status=1, book=BookModel [bookName=Thinking in java, author=AuthorModel [authorName=Bruce Eckel]]] StudentModel [id=4, createTime=Sat Jun 18 00:00:00 GMT+08:00 2016, name=張三3, age=23, studentNo=Stu_3, createUser=王五3, createUserId=null, status=0, book=null] StudentModel [id=5, createTime=Sat Jun 18 00:00:00 GMT+08:00 2016, name=張三4, age=24, studentNo=Stu_4, createUser=王五4, createUserId=null, status=1, book=BookModel [bookName=Thinking in java, author=AuthorModel [authorName=Bruce Eckel]]] StudentModel [id=6, createTime=Sat Jun 18 00:00:00 GMT+08:00 2016, name=張三5, age=25, studentNo=Stu_5, createUser=王五5, createUserId=null, status=0, book=null] StudentModel [id=7, createTime=Sat Jun 18 00:00:00 GMT+08:00 2016, name=張三6, age=26, studentNo=Stu_6, createUser=王五6, createUserId=null, status=1, book=BookModel [bookName=Thinking in java, author=AuthorModel [authorName=Bruce Eckel]]] StudentModel [id=8, createTime=Sat Jun 18 00:00:00 GMT+08:00 2016, name=張三7, age=27, studentNo=Stu_7, createUser=王五7, createUserId=null, status=0, book=null] StudentModel [id=9, createTime=Sat Jun 18 00:00:00 GMT+08:00 2016, name=張三8, age=28, studentNo=Stu_8, createUser=王五8, createUserId=null, status=1, book=BookModel [bookName=Thinking in java, author=AuthorModel [authorName=Bruce Eckel]]] StudentModel [id=10, createTime=Sat Jun 18 00:00:00 GMT+08:00 2016, name=張三9, age=29, studentNo=Stu_9, createUser=王五9, createUserId=null, status=0, book=null]

導入結束,完美導入,其實上面的代碼有些都很多余,那么核心的代碼是哪幾行?

//准備excel文件流 InputStream excelStream = new FileInputStream("C:/Users/Administrator/Desktop/stu.xlsx"); //創建excel上下文實例,它的構成需要配置文件的路徑 ExcelContext context = new ExcelContext("excel-config.xml"); //按照xml配置中id為student的配置形式讀取excel文件,並轉換成StudentModel //這里的第二個參數是值,標題是第幾行開始,之前也說了標題之前的數據並不是規則的數據 ExcelImportResult result = context.readExcel("student", 2,excelStream);

只有准備數據、創建上下文、讀取excel。。通常在真實的常見創建上下文都可以省略了,因為它會交給spring容器管理,整個jvm中,只保持一個實例就夠了。

 

關於導入配置的一個很重要的屬性:resolveFieldValueConverterName

在上面並沒有配置它,這個屬性就是可以解決之前我標記為紅色的問題。那么它是什么?

它是一個ResolveFieldValueConverter接口的實現類:假設我們的Excel中有地址,或者結合業務中可能是其他,都是需要查詢數據庫,或者經過更復雜的業務邏輯進行校驗的,那么我們可以配置它。我們來觀察這個接口做了什么事?

/** * 解析Excel值解析接口 * @author lisuo * */ public interface ResolveFieldValueConverter { /** * 操作類型,導入或導出 */ enum Type { EXPORT, IMPORT } /** * 解析配置中Field元素 處理后的值 * @param bean Excel配置的JavaBean對象 * @param value Excel原值 * @param fieldValue FieldValue信息 * @param type 導入或導出 * @param rowNum 行號 * @return 解析結果對應的value * @throws Exception */ public Object resolveFieldValue(Object bean,Object value, FieldValue fieldValue, Type type,int rowNum) throws Exception; }

核心只有一個方法resolveFieldValue

我們可以自定義它的實現類,然后把全類名注冊到 resolveFieldValueConverterName 屬性上

如:假設創建人是需要查詢用戶表進行校驗java培訓機構,如果沒有則不允許導入,我們則可以在自定義的實現類拋出一個異常, 可以精准的提示用戶多少行,哪一個字段【標題】的值錯誤了。

 

<field name="createUser" title="創建人" resolveFieldValueConverterName="org.easy.excel.test.converter.CreateUserFieldValueConverter"/>

如何使用easy-excel 進行導出?

之前的配置信息完全不變,直接上java代碼

public class ExportTest { public static void main(String[] args) throws Exception { //准備excel輸出流 OutputStream ops = new FileOutputStream("C:/Users/Administrator/Desktop/exportStudent.xlsx"); //創建excel上下文實例,它的構成需要配置文件的路徑 ExcelContext context = new ExcelContext("excel-config.xml"); //獲取POI創建結果 Workbook workbook = context.createExcel("student",getStudents()); workbook.write(ops); ops.close(); workbook.close(); } //獲取模擬數據,數據庫數據... public static List<StudentModel> getStudents(){ int size = 10; List<StudentModel> students = new ArrayList<>(size); for(int i=0;i<size;i++){ StudentModel stu = new StudentModel(); stu.setId(""+(i+1)); stu.setName("張三"+i); stu.setAge(20+i); stu.setStudentNo("Stu_"+i); stu.setCreateTime(new Date()); stu.setStatus(i%2==0?1:0); stu.setCreateUser("王五"+i); //創建復雜對象 if(i % 2==0){ BookModel book = new BookModel(); book.setBookName("Thinking in java"); AuthorModel author = new AuthorModel(); author.setAuthorName("Bruce Eckel"); book.setAuthor(author); stu.setBook(book); } students.add(stu); } return students; } } 

運行結果生成文件:

 

導出的一些疑問?支持樣式么?支持在標題之前創建點其他的信息么?

目前支持cell寬度設置,sheet名稱自定義,標題背景顏色,標題字體顏色,標題對齊方式,單元格樣式是否與標題統一樣式,默認cell對齊方式

對應相關標簽

columnWidth,sheetname,titleBgColor,titleFountColor,align,enableStyle,defaultAlign。

支持導出前自定義頭信息。

--上面紅色標簽部分為最新加入標簽


免責聲明!

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



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