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: