JAVA操作excel生成报表
列标题根据选择的项目动态生成
1 模板文件
2 返回结果集
需要在结果集中对返回的数据进行处理,需要返回所在行数据以及所处项目,从而确定所处单元格的位置。
3将报表统计结果处理后生成报表
///读取excel 模板数据 并且生成报表
private String createFile(String modeID, List<CopyRightFeeExportDTO> list) {
String fileId = "";
try {
///读取流对象
var file = fileHelper.downloadFile(modeID);
//2.读取excel模板,创建excel对象
XSSFWorkbook wb = new XSSFWorkbook(file);
//3.读取sheet对象
Sheet sheet = wb.getSheetAt(0);
//4.定义一些可复用的对象
Row nRow = null;
///获取年份数量
List<String> years = new ArrayList<>();
years = list.stream().map(CopyRightFeeExportDTO::getFYear).distinct().collect(Collectors.toList());
Integer yearCount = years.size();
///获取项目数量
List<String> pubTypes = new ArrayList<>();
pubTypes = list.stream().map(CopyRightFeeExportDTO::getPubType).distinct().collect(Collectors.toList());
Integer pubTypeCount = pubTypes.size();
CellStyle style1 = sheet.getRow(1).getCell(2).getCellStyle();
///模板中的 B3 单元格不可以为空
CellStyle style2 = sheet.getRow(2).getCell(2).getCellStyle();
///循环遍历处理数据 填充单元格
for (int i = 0; i < yearCount; i++) {
int rowNum = i + 2;//对应的行
var rowList = list.stream().filter(x -> x.getRowNum().equals(rowNum)).collect(Collectors.toList());
if (rowList.size() == 0)///如果找不到对应的行 跳出此次循环
break;
if (sheet.getRow(rowNum) == null)
sheet.createRow(rowNum);
nRow = sheet.getRow(rowNum);
for (int j = 0; j < pubTypeCount; j++) {
int pubTypeNum = j;
var dtoList = rowList.stream().filter(x -> x.getColNum().equals(pubTypeNum)).collect(Collectors.toList());
if (dtoList.size() > 0) {
var dto = dtoList.get(0);
if (dto.getColNum().equals(0))///
{
setCellValue(nRow, 0, dto.getFYear(), style1);
应付合计金额
setCellValue(nRow, dto.getColNum() + 1, dto.getPayMoney(), style2);
} else {
///设置表头 第一行
if (sheet.getRow(0).getCell(dto.getColNum() * 4 - 2) == null) {
///创建 第一行和第二行的表头
setCellValue(sheet.getRow(0), dto.getColNum() * 4 - 2, dto.getPubType(), style1);
setCellValue(sheet.getRow(1), dto.getColNum() * 4 - 2, "应付", style1);
setCellValue(sheet.getRow(1), dto.getColNum() * 4 - 1, "已付", style1);
setCellValue(sheet.getRow(1), dto.getColNum() * 4, "已付占比", style1);
setCellValue(sheet.getRow(1), dto.getColNum() * 4 + 1, "未付", style1);
/// 创建B3 数据 总合计
mergeCells(sheet, 0, 0, dto.getColNum() * 4 - 2, dto.getColNum() * 4 + 1);
}
if (dto.getColNum() <= 1) {
setCellValue(sheet.getRow(0), dto.getColNum() * 4 - 2, dto.getPubType(), style1);
}
setCellValue(nRow, dto.getColNum() * 4 - 2, dto.getPayMoney(), style2);
setCellValue(nRow, dto.getColNum() * 4 - 1, dto.getComMoney(), style2);
setCellValue(nRow, dto.getColNum() * 4, dto.getComPercent(), style2);
setCellValue(nRow, dto.getColNum() * 4 + 1, dto.getNoComMoney(), style2);
nRow.setRowStyle(style2);
}
}
}
}
ByteArrayOutputStream bos = new ByteArrayOutputStream();
wb.write(bos); //将工作簿写到输出流中
String fileName = "版权费汇总导出报表.xlsx";
var fileDTO = fileHelper.uploadFile(bos, fileName);
if (fileDTO != null) {
///转成pdf
fileId = fileDTO.getFileId();
}
//合并单元格
} catch (Exception ex) {
log.error("error", ex);
}
return fileId;
}
///合并单元格的方法
private static void mergeCells(Sheet sheet, int firstRow, int lastRow, int firstCol, int lastCol) {
if (lastRow - firstRow == 0 && lastCol - firstCol == 0) {//没有需要合并的单元格
return;
}
CellRangeAddress region = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
sheet.addMergedRegion(region);
}
///给单元格赋值 如果为空的话 需要创建单元格
private void setCellValue(Row nRow, int colNum, String value, CellStyle style) {
if (nRow.getCell(colNum) == null) {
nRow.createCell(colNum);
}
nRow.getCell(colNum).setCellValue(value);
nRow.getCell(colNum).setCellStyle(style);
}
///给单元格赋值 如果为空的话 需要创建单元格
private void setCellValue(Row nRow, int colNum, BigDecimal value, CellStyle style) {
if (nRow.getCell(colNum) == null) {
nRow.createCell(colNum);
}
nRow.getCell(colNum).setCellValue(value.doubleValue());
nRow.getCell(colNum).setCellStyle(style);
}