jXLS是用於生成Excel報表的小型Java類庫。jXLS使用特殊標記在Excel模板中定義輸出格式和數據佈局。java
Java有優秀的建立Excel文件的開源和社區類庫。值得關注的開源類庫有Apache POI和Java Excel API。在某種意義上,這些類庫很是低級,須要編寫許多Java代碼才能建立一個簡單的Excel文件。一般須要手動設置每一個單元格的格式和數據。報表佈局和數據格式越複雜會致使Java代碼很是複雜和難以調試和維護。此外,不是全部的Excel特性都支持和使用API操做(例如,宏或圖表)。apache
在使用jXLS時,你所須要作的就是在一個Excel模板中定義全部報表格式和數據佈局,並運行jXLS引擎,爲它提供數據以填充模板。在大多數狀況下,你須要編寫的惟一代碼是使用適當配置的jXLS引擎的簡單調用。app
Area表明Excel文件中的矩形區域。可使用單元格範圍或使用開始單元格和區域大小(行和列數)定義矩形區域。Area包括特定範圍的全部Excel單元格。函數
每一個Area能夠關聯一組命令,jXLS引擎處理區域時執行和區域相關的命令。Area能夠嵌套子區域。每一個子區域也是一個Area,也能夠包含本身的命令和本身的子區域。佈局
Area可使用如下方式定義:spa
命令表明一個或多個Area的轉換動做。Command接口以下所示: 3d
public interface Command { String getName(); List<Area> getAreaList(); Command addArea(Area area); Size applyAt(CellRef cellRef, Context context); void reset(); }
Command的主要方法是Size applyAt(CellRef cellRef, Context context)。該方法在單元格cellRef執行命令動做。context相似於一個map,用於爲命令傳遞數據。該方法返回轉換後區域的大小做爲Size對象。調試
當前,jXLS提供如下內置命令:excel
Transformer接口容許Area與特定Excel實現無關。這意味着經過提供不一樣的Transformer接口實現,咱們可使用不一樣的底層Java->Excel庫。code
Transformer接口以下所示:
public interface Transformer { void transform(CellRef srcCellRef, CellRef targetCellRef, Context context, boolean updateRowHeight); void setFormula(CellRef cellRef, String formulaString); Set<CellData> getFormulaCells(); CellData getCellData(CellRef cellRef); List<CellRef> getTargetCellRef(CellRef cellRef); void resetTargetCellRefs(); void resetArea(AreaRef areaRef); void clearCell(CellRef cellRef); List<CellData> getCommentedCells(); void addImage(AreaRef areaRef, byte[] imageBytes, ImageType imageType); void write() throws IOException; TransformationConfig getTransformationConfig(); void setTransformationConfig(TransformationConfig transformationConfig); boolean deleteSheet(String sheetName); void setHidden(String sheetName, boolean hidden); void updateRowHeight(String srcSheetName, int srcRowNum, String targetSheetName, int targetRowNum); }
儘管Transformer接口看起來有不少方法,但大多數方法已經在AbstractTransformer基礎抽象類中實現,若是須要提供新Java->Excel實現,只需繼承抽象類便可。
當前,jXLS提供兩種Transformer接口實現:
PoiTransformer使用Apache POI類庫生成Excel文件。JexcelTransformer基於較老的Java Excel API類庫。
jXLS對Apache POI和Java Excel API進行高級封裝,所以,要使用jXLS必須引入底層Apache POI或Java Excel API,毋庸置疑,Apache POI是Java開源社區最強Excel解決方案,所以,咱們選擇使用Apache POI做爲jXLS的底層API。下面是引入Apache POI的依賴配置:
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.15</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.15</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-scratchpad</artifactId> <version>3.15</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-schemas</artifactId> <version>3.15</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-excelant</artifactId> <version>3.15</version> </dependency>
接下來咱們須要引入jXLS的核心類庫:
<dependency> <groupId>org.jxls</groupId> <artifactId>jxls</artifactId> <version>2.4.5</version> </dependency>
jXLS核心類庫,並無直接實現對Excel的操做,而是定義了兩個適配器,分別使用Apache POI和Java Excel API對Excel進行操做。由於咱們選擇使用Apache POI做爲底層API操做Excel,所以,咱們須要導入Apache POI適配器依賴:
<dependency> <groupId>org.jxls</groupId> <artifactId>jxls-poi</artifactId> <version>1.0.15</version> </dependency>
一個完整的Maven依賴配置以下所示:
<!-- jXLS核心庫 --> <dependency> <groupId>org.jxls</groupId> <artifactId>jxls</artifactId> <version>2.4.5</version> </dependency> <!-- jXLS-POI適配器 --> <dependency> <groupId>org.jxls</groupId> <artifactId>jxls-poi</artifactId> <version>1.0.15</version> </dependency> <!-- Apache POI依賴包 --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.15</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.15</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-scratchpad</artifactId> <version>3.15</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-schemas</artifactId> <version>3.15</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-excelant</artifactId> <version>3.15</version> </dependency>
/** * 員工實體類 * * @since 2018年7月11日 * @author 趙凡 * @version 1.0 * */ public class Employee { private String name;// 員工名稱 private String sex;// 性別 private String telephone;// 手機號碼 private Date birthday;// 生日 private BigDecimal payment;// 工資 // ... 構造函數 // ... getters/setters }
模板是使用特定標記規定jXLS應該如何輸出數據的Excel文件。jXLS提供一些內置標記處理器解析Excel模板和提取控制命令。若有須要能夠自定義標記處理器。所以,能夠爲Excel模板定義本身的標記,並以適當的方式進行解析,以建立jXLS命令結構。
默認,jXLS以Apache JEXL做爲表達式語言在Excel模板中引用Java對象屬性和方法。對象必須在jXLS上下文中某一鍵上可用。爲了在單元格中輸出員工名稱,能夠在單元格中放入${employee.name}。使用${和}環繞JEXL表達式。假設在上下文中employee鍵下有一個Employee對象。
輸出員工列表信息的最終模板以下所示:
模板中第三行的單元格使用JEXL表達式引用employee對象的屬性。單元格A1包含的Excel註釋jx:area(lastCell="E4")定義模板根區域爲A1:E4。單元格A3包含的Excel註釋jx:each(items="employees" var="employee" lastCell="E4")定義jXLS Each命令。Each命令迭代employees(由items屬性定義)集合的條目到上下文的employee(由var屬性定義)鍵。執行Each命令的區域是A3:E4(有lastCell屬性定義),該區域將會被克隆,並使用上下文中的每一個新的Employee對象處理。
List<Employee> employees = generateSampleEmployeeData(); try(InputStream is = ObjectCollectionDemo.class.getResourceAsStream("object_collection_template.xls")) { try (OutputStream os = new FileOutputStream("target/object_collection_output.xls")) { Context context = new Context(); context.putVar("employees", employees); JxlsHelper.getInstance().processTemplate(is, os, context); } }
運行程序生成以下所示的Excel: