通过JXLS2实现如下折叠的表格的导出。
如一个Lead下面管理了多个人员,将下属人员折叠起来,点击后展开下属的人员列表。
在官方自带的文档中自带了实现分组折叠的DEMO,我们在这基础上稍作改动即可实现以上的分组折叠效果。
<dependency>
<groupId>org.jxlsgroupId>
<artifactId>jxlsartifactId>
<version>2.6.0version>
dependency>
<dependency>
<groupId>org.jxlsgroupId>
<artifactId>jxls-poiartifactId>
<version>1.2.0version>
dependency>
以下代码来自于官方jxls-examples的demo模块下,创建了一个新的jxls命令:groupRow。
import org.jxls.area.Area;
import org.jxls.command.AbstractCommand;
import org.jxls.command.Command;
import org.jxls.common.CellRef;
import org.jxls.common.Context;
import org.jxls.common.Size;
import org.jxls.transform.poi.PoiTransformer;
import org.jxls.util.Util;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
public class GroupRowCommand extends AbstractCommand {
Area area;
String collapseIf;
public String getName() {
return "groupRow";
}
public Size applyAt(CellRef cellRef, Context context) {
Size resultSize = area.applyAt(cellRef, context);
if( resultSize.equals(Size.ZERO_SIZE)) return resultSize;
PoiTransformer transformer = (PoiTransformer) area.getTransformer();
Workbook workbook = transformer.getWorkbook();
Sheet sheet = workbook.getSheet(cellRef.getSheetName());
int startRow = cellRef.getRow();
int endRow = cellRef.getRow() + resultSize.getHeight() - 1;
sheet.groupRow(startRow, endRow);
if( collapseIf != null && collapseIf.trim().length() > 0){
boolean collapseFlag = Util.isConditionTrue(getTransformationConfig().getExpressionEvaluator(), collapseIf, context);
sheet.setRowGroupCollapsed(startRow, collapseFlag);
}
return resultSize;
}
@Override
public Command addArea(Area area) {
super.addArea(area);
this.area = area;
return this;
}
public void setCollapseIf(String collapseIf) {
this.collapseIf = collapseIf;
}
}
JXLS参考:
JXLS官网
JXLS的API.
以下举个简单的例子:
public class Employee {
private String name;
private int age;
private Double payment;
private Double bonus;
private Date birthDate;
private List<Employee> employees;
/**此处省略构造函数及get和set方法**/
}
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.jxls.area.Area;
import org.jxls.builder.AreaBuilder;
import org.jxls.builder.xls.XlsCommentAreaBuilder;
import org.jxls.common.CellRef;
import org.jxls.common.Context;
import org.jxls.demo.model.Employee;
import org.jxls.transform.Transformer;
import org.jxls.util.TransformerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class UserCommandExcelMarkupDemo {
static Logger logger = LoggerFactory.getLogger(UserCommandExcelMarkupDemo.class);
private static String template = "user_command_markup_template.xls";
private static String output = "target/user_command_markup_output.xls";
public static void main(String[] args) throws IOException, InvalidFormatException, ParseException {
logger.info("Running User Command Markup demo");
execute();
}
public static void execute() throws IOException, InvalidFormatException, ParseException {
List<Employee> employees = generateSampleEmployeeData();
logger.info("Opening input stream");
try (InputStream is = UserCommandExcelMarkupDemo.class.getResourceAsStream(template)) {
try (OutputStream os = new FileOutputStream(output)) {
Transformer transformer = TransformerFactory.createTransformer(is, os);
AreaBuilder areaBuilder = new XlsCommentAreaBuilder(transformer);
/**添加自定义命令**/
XlsCommentAreaBuilder.addCommandMapping("groupRow", GroupRowCommand.class);
List<Area> xlsAreaList = areaBuilder.build();
Area xlsArea = xlsAreaList.get(0);
Context context = new Context();
context.putVar("employees", employees);
xlsArea.applyAt(new CellRef("Result!A1"), context);
transformer.write();
logger.info("Finished UserCommandExcelMarkupDemo");
}
}
}
private static List<Employee> generateSampleEmployeeData() throws ParseException {
List<Employee> employees = new ArrayList<>();
List<Employee> employees2 = new ArrayList<>();
List<Employee> leadEmployees = new ArrayList<>();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MMM-dd", Locale.US);
employees.add(new Employee("Elsa", dateFormat.parse("1970-Jul-10"), 1500d, 0.15));
employees.add(new Employee("Oleg", dateFormat.parse("1973-Apr-30"), 2300d, 0.25));
employees.add(new Employee("Neil", dateFormat.parse("1975-Oct-05"), 2500d, 0.00));
employees.add(new Employee("Maria", dateFormat.parse("1978-Jan-07"), 1700d, 0.15));
employees.add(new Employee("John", dateFormat.parse("1969-May-30"), 2800d, 0.20));
employees2.add(new Employee("Elsa1", dateFormat.parse("1970-Jul-10"), 1500d, 0.15));
employees2.add(new Employee("Oleg1", dateFormat.parse("1973-Apr-30"), 2300d, 0.25));
employees2.add(new Employee("Neil1", dateFormat.parse("1975-Oct-05"), 2500d, 0.00));
leadEmployees.add(new Employee("Lead1", dateFormat.parse("1969-May-30"), 12800d, 0.50, employees));
leadEmployees.add(new Employee("Lead2", dateFormat.parse("1979-May-30"), 22800d, 0.50, employees2));
return leadEmployees;
}
}
以上就能实现文章开头展示的情况。