Java解决一个Excel文件中多个模板打印问题

报表打印是很多地方都需要用到的,其需求也是多种多样,
以下旨在解决要求:一个Excel模板文件中包含多个sheet页模板,且有汇总模板和多个明细模板;打印结果要求:汇总模板是汇总数据,根据汇总模板的数据,再打出汇总数据中不同类型的明细数据。比如:汇总数据包含三种类型的明细数据,明细数据分别有10,15,13条数据,因此,报表结果为一个sheet页为汇总数据,10个sheet页为明细数据1,15个sheet页为明细数据2,13个sheet页为明细数据3.
以下为具体代码:

public static void main(String[] args) throws IOException {
// 获取本地模板
InputStream excelInputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(“excel/templateInfo.xlsx”);
if (excelInputStream != null) {
Workbook sourceWorkbook = new XSSFWorkbook(excelInputStream);
//需打印的数据
Map<String, List> templateInfo = new HashMap<>();
//根据需要复制一个新的模板
InputStream inputStream = copyExcelTemplate(sourceWorkbook,templateInfo);
ZipSecureFile.setMinInflateRatio(0.001);
//输出参数,可以是文件,或file,或output,或文件路径
Object outputStream = null;
//向模板中填充数据,这里使用阿里的EasyExcel
ExcelWriter excelWriter = EasyExcel.write((File) outputStream).withTemplate(inputStream).build();
//为汇总模板赋值
WriteSheet writerSheet = EasyExcel.writerSheet(0).build();
excelWriter.fill(templateInfo.get(“TEMPLATEINFO1”), writerSheet);
int num1 = 1;
int num2 = 0;
int num3 = 0;
//为第四个模板赋值
List templateinfo2 = templateInfo.get(“TEMPLATEINFO2”);
if (templateinfo2 != null && templateinfo2.size() > 0){
num2 = templateinfo2.size() + num1;
for (int i = 0; i < templateinfo2.size(); i++) {
Object temp2 = templateinfo2.get(i);
WriteSheet writerSheetNew = EasyExcel.writerSheet(num1 + i).head(Object.class).build();
excelWriter.fill(temp2, writerSheetNew);
}
}
//为第三个模板赋值
List templateinfo3 = templateInfo.get(“TEMPLATEINFO3”);
if (templateinfo3 != null && templateinfo3.size() > 0){
num3 = num2 == 0 ? num1 : num2 + templateinfo3.size();
num2 = num2 == 0 ? num1 : num2 ;
for (int i = 0; i < templateinfo3.size(); i++) {
Object temp3 = templateinfo3.get(i);
WriteSheet writerSheetSolutions = EasyExcel.writerSheet(num2 + i).build();
excelWriter.fill(temp3, writerSheetSolutions);
}
}
//为第四个模板赋值
List templateinfo4 = templateInfo.get(“TEMPLATEINFO4”);
if (templateinfo4 != null && templateinfo4.size() > 0){
num3 = num3 == 0 ? num2 == 0 ? num1 : num2 : num3 ;
for (int i = 0; i < templateinfo4.size(); i++) {
Object temp4 = templateinfo4.get(i);
WriteSheet writerSheetStock = EasyExcel.writerSheet(num3 + i).head(Object.class).build();
excelWriter.fill(temp4, writerSheetStock);
}
}
excelWriter.finish();
} else {
System.out.println(“模板文件不存在”);
}
}
public static InputStream copyExcelTemplate(Workbook sourceWorkbook, Map<String, List> templateInfo){
InputStream excelInputStream = null;
//取出每个类型的总数
List<Map<String,String>> templateInfo1 = templateInfo.get(“TEMPLATEINFO1”);
List<Map<String,String>> templateInfo2 = templateInfo.get(“TEMPLATEINFO2”);
List<Map<String,String>> templateInfo3 = templateInfo.get(“TEMPLATEINFO3”);
List<Map<String,String>> templateInfo4 = templateInfo.get(“TEMPLATEINFO4”);
Workbook newWorkbook = new XSSFWorkbook();
//汇总数据只需要一个模板
if (templateInfo1 != null && templateInfo1.size() > 0){
Sheet newSheet = newWorkbook.createSheet(“汇总数据”);
//根据第一个模板复制
copyFormat(newWorkbook,newSheet,sourceWorkbook.getSheetAt(0));
}
//其他模板sheet页需要根据具体的数据数量复制
if (templateInfo2 != null && templateInfo2.size() > 0){
for (int i = 0; i < templateInfo2.size(); i++) {
Sheet newSheet = newWorkbook.createSheet(“模板sheet1” + i);
//根据第二个模板复制
copyFormat(newWorkbook,newSheet,sourceWorkbook.getSheetAt(1));
}
}
if (templateInfo3 != null && templateInfo3.size() > 0){
for (int i = 0; i < templateInfo3.size(); i++) {
Sheet newSheet = newWorkbook.createSheet(“模板sheet2” + i);
//根据第三个模板复制
copyFormat(newWorkbook,newSheet,sourceWorkbook.getSheetAt(2));
}
}
if (templateInfo4 != null && templateInfo4.size() > 0){
for (int i = 0; i < templateInfo4.size(); i++) {
Sheet newSheet = newWorkbook.createSheet(“模板sheet3” + i);
//根据第四个模板复制
copyFormat(newWorkbook,newSheet,sourceWorkbook.getSheetAt(3));
}
}
try {
//此处返回工作流的方式可以解决测试和生产环境代码无法创建文件的问题
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
newWorkbook.write(outputStream);
//将ByteArrayOutputStream对象转换为ByteArrayInputStream
excelInputStream = new ByteArrayInputStream(outputStream.toByteArray());
newWorkbook.close();
outputStream.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
return excelInputStream;
}
/**
* 为新模板单元格添加格式
* 由于此方法复制的方式是每行每个单元格依次复制,
* 所以此方法会造成效率低
* @param newWorkbook 要写入的文件
* @param newSheet 要添加格式的sheet页
* @param sourceSheet 模板sheet页
*/
public void copyFormat(Workbook newWorkbook,Sheet newSheet,Sheet sourceSheet){
// 复制合并单元格区域
for (CellRangeAddress mergedRegion : sourceSheet.getMergedRegions()) {
newSheet.addMergedRegion(mergedRegion);
}
// 复制行、单元格和单元格宽度
for (int i = 0; i <= sourceSheet.getLastRowNum(); i++) {
Row sourceRow = sourceSheet.getRow(i);
if (sourceRow != null) {
//创建新的一行
Row newRow = newSheet.createRow(i);
newRow.setHeight(sourceRow.getHeight()); // 复制行高
for (int j = 0; j < sourceRow.getLastCellNum(); j++) {
Cell sourceCell = sourceRow.getCell(j);
if (sourceCell != null) {
//创建新的一个单元格
Cell newCell = newRow.createCell(j);
newCell.setCellType(sourceCell.getCellType());
// 复制单元格样式
CellStyle sourceCellStyle = sourceCell.getCellStyle();
CellStyle newCellStyle = newWorkbook.createCellStyle();
newCellStyle.cloneStyleFrom(sourceCellStyle);
newCell.setCellStyle(newCellStyle);
// 复制单元格值,可以根据需要添加
switch (sourceCell.getCellType()) {
case HSSFCell.CELL_TYPE_STRING:
newCell.setCellValue(sourceCell.getStringCellValue());
break;
case HSSFCell.CELL_TYPE_NUMERIC:
newCell.setCellValue(sourceCell.getNumericCellValue());
break;
}
}
}
// 创建指向Sheet2的超链接
/CreationHelper createHelper = newWorkbook.getCreationHelper();
Hyperlink link = createHelper.createHyperlink(HyperlinkType.DOCUMENT);
link.setAddress(“‘Sheet2’!A1”); // 设置超链接地址,指向Sheet2的A1单元格
cell1.setHyperlink(link);
/
// 复制列宽
for (int k = 0; k < sourceRow.getLastCellNum(); k++) {
newSheet.setColumnWidth(k, sourceSheet.getColumnWidth(k));
}
}
}
// 自动调整列宽(如果需要,不建议使用,会导致原模板格式失效)
/for (int i = 0; i <= sourceSheet.getLastRowNum(); i++) {
Row sourceRow = sourceSheet.getRow(i);
if (sourceRow != null) {
for (int j = 0; j < sourceRow.getLastCellNum(); j++) {
Cell sourceCell = sourceRow.getCell(j);
if (sourceCell != null) {
newSheet.autoSizeColumn(j); // 根据内容自动调整列宽
}
}
}
}
/
}

  • 31
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值