請務必先看上一篇文章,本文在上一篇文章的代碼基礎上修改而成。
上一篇文章我們介紹了JXLS和模板導出最簡單的應用,現在我們要更進一步,介紹在模板中循環導出鏈表中的數據,在日常開發中,循環導出應該才是最常用的功能吧!
首先,我們要建立一個類模擬javabean對象。我們定義一個person類,里面有id,name和age。
public class Person { String id; String name; Integer age; public Person(String id, String name, Integer age) { super(); this.id = id; this.name = name; this.age = age; } public Person() { } /** 以下省略了對應的get/set方法,請自行補齊 */ }
然后我們修改main 方法,大體上和上一篇文章是一致的,只是模擬了從數據庫取出javabean的過程,將取出的javabean對象放入model中,然后傳給JxlsUtils。
public class TestMain { public static void main(String[] args) throws Exception { // 模板位置,輸出流
String templatePath = "E:/template2.xls"; OutputStream os = new FileOutputStream("E:/out.xls"); // 一個裝有對象數據的鏈表
List<Person> persons = new ArrayList<Person>(); Person p1 = new Person("001", "張三", 18); Person p2 = new Person("002", "李四", 19); Person p3 = new Person("003", "王五", 20); persons.add(p1); persons.add(p2); persons.add(p3); Map<String, Object> model = new HashMap<String, Object>(); model.put("person", persons); // 把鏈表放進model中
JxlsUtils.exportExcel(templatePath, os, model); os.close(); System.out.println("完成"); } }
接下來我們設計模板:
A1單元格(A1到C1合並單元格,名字還是A1)中的注釋:jx:area(lastCell="D4"),不用多講划定模板的區域范圍。依照上文講的避免bug的原因,我們依然將區域范圍設置成比模板內容至少大一圈。需要說明的是注釋必須在左上角的A1中,但是可以在和A1合並后的單元格中。
A3單元格的注釋:jx:each(items="person" var="p" lastCell="C3"):
jx:each() 這是一個遍歷注釋,默認向下增加一行。官網寫可以橫向遍歷(增加direction 參數),我沒有試過。
Items= 從java代碼中傳入的model的鍵值對中取出鍵名為“person”的對象,這個對象可以是集合,一般是鏈表。
Var= 每一條記錄的變量名,命名為p。
lastCell= 遍歷數據在模板中最后一個單元格的位置。
然后在遍歷的區域內寫上${ } 表達式,以var中定義的變量名 . 傳進來的對象屬性為構成。
然后保存模板,執行java代碼,就能看到下圖的結果了。
我們再來測試下復雜一點的模板呢?
遍歷的模板有兩行,而且開頭一列為合並的單元格,遍歷模板第二行為有底紋的單元格,看看整個表格生成后會不會崩掉?我試過幾個模板導出插件,很多都是單行遍歷模板沒問題,一旦出現多行數據和帶有合並的單元格整個模板就會崩掉。
沒毛病,完美。
最后說一點:如果lastCell的參數的值要設定為一個合並后的單元格,你不知道這個合並后的單元格名字是什么,那就用鼠標點一下該單元格,excel左上角會顯示這個合並單元格的名稱的,就寫這個名字就行。
例如上圖001所在的合並單元格,用數據點擊后excel提示的單元格名稱為A3,其實寫A3,A4都行。
2018-08-07 新增:
還有一種用法,就是橫向遍歷顯示list的數據。其實很簡單,jx:each的注釋里只要寫direction="RIGHT"就行了。
jx:each(items="data" var="dat" lastCell="A3" direction="RIGHT")
具體參照下圖,我就不寫代碼了,都一樣,只是模板的不同而已。