导出优化
This commit is contained in:
parent
848ec53939
commit
e9970d5057
@ -9,6 +9,7 @@ import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
|
|||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
import net.lab1024.sa.admin.module.app.medicalrecord.service.MedicalRecordService;
|
import net.lab1024.sa.admin.module.app.medicalrecord.service.MedicalRecordService;
|
||||||
|
import net.lab1024.sa.admin.module.business.caseplatformcase.converter.CustomExcelWriteHandler;
|
||||||
import net.lab1024.sa.admin.module.business.caseplatformcase.domain.form.CaseplatformCaseQueryForm;
|
import net.lab1024.sa.admin.module.business.caseplatformcase.domain.form.CaseplatformCaseQueryForm;
|
||||||
import net.lab1024.sa.admin.module.business.caseplatformcase.domain.vo.EasyExcelCaseDetailVO;
|
import net.lab1024.sa.admin.module.business.caseplatformcase.domain.vo.EasyExcelCaseDetailVO;
|
||||||
import net.lab1024.sa.admin.module.business.caseplatformcase.domain.vo.ExportExpertCaseExcelVo;
|
import net.lab1024.sa.admin.module.business.caseplatformcase.domain.vo.ExportExpertCaseExcelVo;
|
||||||
@ -94,58 +95,58 @@ public class CaseplatformCaseExcelController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 结算导出
|
// 结算导出
|
||||||
@ApiOperation("结算导出")
|
// @ApiOperation("结算导出")
|
||||||
@GetMapping("/caseplatformCase/settlementExcel")
|
// @GetMapping("/caseplatformCase/settlementExcel")
|
||||||
@PreAuthorize("@saAuth.checkPermission('case-system:case:exportExpertCaseExceli')")
|
// @PreAuthorize("@saAuth.checkPermission('case-system:case:exportExpertCaseExceli')")
|
||||||
public void exportExpertCaseExceli(HttpServletResponse response, @Valid CaseplatformCaseQueryForm queryForm) {
|
// public void exportExpertCaseExceli(HttpServletResponse response, @Valid CaseplatformCaseQueryForm queryForm) {
|
||||||
try {
|
// try {
|
||||||
List<ExportExpertCaseExcelVo> list = caseplatformCaseService.exportExpertCaseExcel(queryForm);
|
// List<ExportExpertCaseExcelVo> list = caseplatformCaseService.exportExpertCaseExcel(queryForm);
|
||||||
List<ExportExpertCaseExcelVo> processedList = caseplatformCaseService.exportExpertCaseExcelProcess(list);
|
// List<ExportExpertCaseExcelVo> processedList = caseplatformCaseService.exportExpertCaseExcelProcess(list);
|
||||||
|
//
|
||||||
// 总计
|
// // 总计
|
||||||
double totalActual = processedList.stream().mapToDouble(e -> Optional.ofNullable(e.getActualAmount()).orElse(0.0)).sum();
|
// double totalActual = processedList.stream().mapToDouble(e -> Optional.ofNullable(e.getActualAmount()).orElse(0.0)).sum();
|
||||||
double totalTax = processedList.stream().mapToDouble(e -> Optional.ofNullable(e.getTaxAmount()).orElse(0.0)).sum();
|
// double totalTax = processedList.stream().mapToDouble(e -> Optional.ofNullable(e.getTaxAmount()).orElse(0.0)).sum();
|
||||||
double totalTotal = processedList.stream().mapToDouble(e -> Optional.ofNullable(e.getTotalAmount()).orElse(0.0)).sum();
|
// double totalTotal = processedList.stream().mapToDouble(e -> Optional.ofNullable(e.getTotalAmount()).orElse(0.0)).sum();
|
||||||
|
//
|
||||||
String filePath = "./人工肝诊疗专家劳务费.xlsx";
|
// String filePath = "./人工肝诊疗专家劳务费.xlsx";
|
||||||
FileOutputStream outputStream = new FileOutputStream(filePath);
|
// FileOutputStream outputStream = new FileOutputStream(filePath);
|
||||||
|
//
|
||||||
// 字段标题
|
// // 字段标题
|
||||||
List<List<String>> head = Arrays.asList(
|
// List<List<String>> head = Arrays.asList(
|
||||||
Collections.singletonList("序号"),
|
// Collections.singletonList("序号"),
|
||||||
Collections.singletonList("银行"),
|
// Collections.singletonList("银行"),
|
||||||
Collections.singletonList("账号所在省份"),
|
// Collections.singletonList("账号所在省份"),
|
||||||
Collections.singletonList("账户所在地市"),
|
// Collections.singletonList("账户所在地市"),
|
||||||
Collections.singletonList("卡号"),
|
// Collections.singletonList("卡号"),
|
||||||
Collections.singletonList("姓名"),
|
// Collections.singletonList("姓名"),
|
||||||
Collections.singletonList("实发"),
|
// Collections.singletonList("实发"),
|
||||||
Collections.singletonList("备注"),
|
// Collections.singletonList("备注"),
|
||||||
Collections.singletonList("个税"),
|
// Collections.singletonList("个税"),
|
||||||
Collections.singletonList("应发"),
|
// Collections.singletonList("应发"),
|
||||||
Collections.singletonList("单位"),
|
// Collections.singletonList("单位"),
|
||||||
Collections.singletonList("电话"),
|
// Collections.singletonList("电话"),
|
||||||
Collections.singletonList("身份证号"),
|
// Collections.singletonList("身份证号"),
|
||||||
Collections.singletonList("关联病例")
|
// Collections.singletonList("关联病例")
|
||||||
);
|
// );
|
||||||
|
//
|
||||||
WriteCellStyle headStyle = new WriteCellStyle();
|
// WriteCellStyle headStyle = new WriteCellStyle();
|
||||||
headStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
|
// headStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
|
||||||
headStyle.setVerticalAlignment(VerticalAlignment.CENTER);
|
// headStyle.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||||
headStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
|
// headStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
|
||||||
headStyle.setBorderBottom(BorderStyle.THIN);
|
// headStyle.setBorderBottom(BorderStyle.THIN);
|
||||||
headStyle.setBorderTop(BorderStyle.THIN);
|
// headStyle.setBorderTop(BorderStyle.THIN);
|
||||||
headStyle.setBorderLeft(BorderStyle.THIN);
|
// headStyle.setBorderLeft(BorderStyle.THIN);
|
||||||
headStyle.setBorderRight(BorderStyle.THIN);
|
// headStyle.setBorderRight(BorderStyle.THIN);
|
||||||
|
//
|
||||||
WriteCellStyle contentStyle = new WriteCellStyle();
|
// WriteCellStyle contentStyle = new WriteCellStyle();
|
||||||
contentStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
|
// contentStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
|
||||||
contentStyle.setVerticalAlignment(VerticalAlignment.CENTER);
|
// contentStyle.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||||
contentStyle.setBorderBottom(BorderStyle.THIN);
|
// contentStyle.setBorderBottom(BorderStyle.THIN);
|
||||||
contentStyle.setBorderTop(BorderStyle.THIN);
|
// contentStyle.setBorderTop(BorderStyle.THIN);
|
||||||
contentStyle.setBorderLeft(BorderStyle.THIN);
|
// contentStyle.setBorderLeft(BorderStyle.THIN);
|
||||||
contentStyle.setBorderRight(BorderStyle.THIN);
|
// contentStyle.setBorderRight(BorderStyle.THIN);
|
||||||
|
//
|
||||||
// ExcelWriter writer = EasyExcel.write(outputStream, ExportExpertCaseExcelVo.class)
|
//// ExcelWriter writer = EasyExcel.write(outputStream, ExportExpertCaseExcelVo.class)
|
||||||
// ExcelWriter writer = EasyExcel.write(response.getOutputStream(), ExportExpertCaseExcelVo.class)
|
// ExcelWriter writer = EasyExcel.write(response.getOutputStream(), ExportExpertCaseExcelVo.class)
|
||||||
// .head(head)
|
// .head(head)
|
||||||
// .excelType(ExcelTypeEnum.XLSX)
|
// .excelType(ExcelTypeEnum.XLSX)
|
||||||
@ -169,129 +170,175 @@ public class CaseplatformCaseExcelController {
|
|||||||
// if (titleRow == null) {
|
// if (titleRow == null) {
|
||||||
// titleRow = sheet.createRow(0);
|
// titleRow = sheet.createRow(0);
|
||||||
// }
|
// }
|
||||||
|
// titleRow.setHeightInPoints(30); // 设置标题行高
|
||||||
|
// Cell titleCell = titleRow.createCell(0);
|
||||||
|
// titleCell.setCellValue("人工肝诊疗病例征集项目专家劳务费表");
|
||||||
|
// CellStyle titleStyle = workbook.createCellStyle();
|
||||||
|
// Font font = workbook.createFont();
|
||||||
|
// font.setFontHeightInPoints((short) 16);
|
||||||
|
// font.setBold(true);
|
||||||
|
// titleStyle.setFont(font);
|
||||||
|
// titleStyle.setAlignment(HorizontalAlignment.CENTER);
|
||||||
|
// titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||||
|
// titleStyle.setBorderRight(BorderStyle.THIN); // 最后一格加右边框
|
||||||
|
// titleCell.setCellStyle(titleStyle);
|
||||||
|
//
|
||||||
|
// // === 设置行高 ===
|
||||||
|
// sheet.getRow(1).setHeightInPoints(25); // 表头行
|
||||||
|
// for (int i = 2; i <= processedList.size() + 2; i++) {
|
||||||
|
// Row row = sheet.getRow(i);
|
||||||
|
// if (row != null) {
|
||||||
|
// row.setHeightInPoints(22);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // === 设置列宽 ===
|
||||||
|
// int[] columnWidths = {
|
||||||
|
// 6, 25, 15, 15, 25, 10, 10, 30, 8, 8, 30, 25, 30, 15
|
||||||
|
// };
|
||||||
|
// for (int i = 0; i < columnWidths.length; i++) {
|
||||||
|
// sheet.setColumnWidth(i, columnWidths[i] * 256); // 乘 256 为 Excel 单位
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // 写合计行
|
||||||
|
// int totalRowIndex = processedList.size() + 2; // +1是数据从第3行开始,+2是表头行数
|
||||||
|
// Row totalRow = sheet.createRow(totalRowIndex);
|
||||||
|
// totalRow.setHeightInPoints(22);
|
||||||
|
//
|
||||||
|
// // 合计行样式(黑底白字)
|
||||||
|
// CellStyle totalStyle = workbook.createCellStyle();
|
||||||
|
// Font totalFont = workbook.createFont();
|
||||||
|
// totalFont.setBold(true);
|
||||||
|
// totalFont.setColor(IndexedColors.WHITE.getIndex());
|
||||||
|
// totalStyle.setFont(totalFont);
|
||||||
|
// totalStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||||
|
// totalStyle.setAlignment(HorizontalAlignment.CENTER);
|
||||||
|
// totalStyle.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||||
|
// totalStyle.setBorderTop(BorderStyle.THIN);
|
||||||
|
// totalStyle.setBorderBottom(BorderStyle.THIN);
|
||||||
|
// totalStyle.setBorderLeft(BorderStyle.THIN);
|
||||||
|
// totalStyle.setBorderRight(BorderStyle.THIN);
|
||||||
|
//
|
||||||
|
// // 合并前3列,写“合计”
|
||||||
|
// sheet.addMergedRegion(new CellRangeAddress(totalRowIndex, totalRowIndex, 0, 5));
|
||||||
|
// Cell cell0 = totalRow.createCell(0);
|
||||||
|
// cell0.setCellValue("合计");
|
||||||
|
//
|
||||||
|
// // 设置边框样式
|
||||||
|
// CellStyle borderStyle = workbook.createCellStyle();
|
||||||
|
// borderStyle.setBorderBottom(BorderStyle.THIN);
|
||||||
|
// borderStyle.setBorderTop(BorderStyle.THIN);
|
||||||
|
// borderStyle.setBorderLeft(BorderStyle.THIN);
|
||||||
|
// borderStyle.setBorderRight(BorderStyle.THIN);
|
||||||
|
// borderStyle.setAlignment(HorizontalAlignment.CENTER);
|
||||||
|
//
|
||||||
|
// // 创建合计单元格并添加边框
|
||||||
|
// for (int i = 0; i < head.size(); i++) {
|
||||||
|
// Cell cell = totalRow.getCell(i);
|
||||||
|
// if (cell == null) {
|
||||||
|
// cell = totalRow.createCell(i);
|
||||||
|
// }
|
||||||
|
// cell.setCellStyle(borderStyle);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // 实发(列 G = index 6)、个税(I = 8)、应发(J = 9)
|
||||||
|
// totalRow.getCell(6).setCellValue(totalActual);
|
||||||
|
// totalRow.getCell(8).setCellValue(totalTax);
|
||||||
|
// totalRow.getCell(9).setCellValue(totalTotal);
|
||||||
|
//
|
||||||
|
// // 6通知浏览器以附件的形式下载处理,设置返回头要注意文件名有中文
|
||||||
|
// String fileName = URLEncoder.encode("病例数据", "UTF-8").replaceAll("\\+", "%20");
|
||||||
|
// response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
|
||||||
|
// response.setContentType("multipart/form-data");
|
||||||
|
// response.setCharacterEncoding("utf-8");
|
||||||
|
// writer.finish();
|
||||||
|
//
|
||||||
|
// outputStream.close();
|
||||||
|
//
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// e.printStackTrace();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
@ApiOperation("结算导出")
|
||||||
|
@GetMapping("/caseplatformCase/settlementExcel")
|
||||||
|
@PreAuthorize("@saAuth.checkPermission('case-system:case:exportExpertCaseExceli')")
|
||||||
|
public void exportExpertCaseExceli(HttpServletResponse response, @Valid CaseplatformCaseQueryForm queryForm) {
|
||||||
|
try {
|
||||||
|
List<ExportExpertCaseExcelVo> list = caseplatformCaseService.exportExpertCaseExcel(queryForm);
|
||||||
|
List<ExportExpertCaseExcelVo> processedList = caseplatformCaseService.exportExpertCaseExcelProcess(list);
|
||||||
|
|
||||||
// 1. 构建ExcelWriter(先不写入数据,先处理大标题行)
|
// 总计
|
||||||
|
double totalActual = processedList.stream().mapToDouble(e -> Optional.ofNullable(e.getActualAmount()).orElse(0.0)).sum();
|
||||||
|
double totalTax = processedList.stream().mapToDouble(e -> Optional.ofNullable(e.getTaxAmount()).orElse(0.0)).sum();
|
||||||
|
double totalTotal = processedList.stream().mapToDouble(e -> Optional.ofNullable(e.getTotalAmount()).orElse(0.0)).sum();
|
||||||
|
|
||||||
|
// 字段标题
|
||||||
|
List<List<String>> head = Arrays.asList(
|
||||||
|
Collections.singletonList("序号"),
|
||||||
|
Collections.singletonList("银行"),
|
||||||
|
Collections.singletonList("账号所在省份"),
|
||||||
|
Collections.singletonList("账户所在地市"),
|
||||||
|
Collections.singletonList("卡号"),
|
||||||
|
Collections.singletonList("姓名"),
|
||||||
|
Collections.singletonList("实发"),
|
||||||
|
Collections.singletonList("备注"),
|
||||||
|
Collections.singletonList("个税"),
|
||||||
|
Collections.singletonList("应发"),
|
||||||
|
Collections.singletonList("单位"),
|
||||||
|
Collections.singletonList("电话"),
|
||||||
|
Collections.singletonList("身份证号"),
|
||||||
|
Collections.singletonList("关联病例")
|
||||||
|
);
|
||||||
|
|
||||||
|
// 1. 配置样式策略
|
||||||
|
WriteCellStyle headStyle = new WriteCellStyle();
|
||||||
|
headStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
|
||||||
|
headStyle.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||||
|
headStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
|
||||||
|
headStyle.setBorderBottom(BorderStyle.THIN);
|
||||||
|
headStyle.setBorderTop(BorderStyle.THIN);
|
||||||
|
headStyle.setBorderLeft(BorderStyle.THIN);
|
||||||
|
headStyle.setBorderRight(BorderStyle.THIN);
|
||||||
|
|
||||||
|
WriteCellStyle contentStyle = new WriteCellStyle();
|
||||||
|
contentStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
|
||||||
|
contentStyle.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||||
|
contentStyle.setBorderBottom(BorderStyle.THIN);
|
||||||
|
contentStyle.setBorderTop(BorderStyle.THIN);
|
||||||
|
contentStyle.setBorderLeft(BorderStyle.THIN);
|
||||||
|
contentStyle.setBorderRight(BorderStyle.THIN);
|
||||||
|
|
||||||
|
// 2. 初始化 ExcelWriter(仅使用响应输出流,移除本地文件输出)
|
||||||
ExcelWriter writer = EasyExcel.write(response.getOutputStream(), ExportExpertCaseExcelVo.class)
|
ExcelWriter writer = EasyExcel.write(response.getOutputStream(), ExportExpertCaseExcelVo.class)
|
||||||
.head(head)
|
.head(head)
|
||||||
.excelType(ExcelTypeEnum.XLSX)
|
.excelType(ExcelTypeEnum.XLSX)
|
||||||
.registerWriteHandler(new HorizontalCellStyleStrategy(headStyle, contentStyle))
|
.registerWriteHandler(new HorizontalCellStyleStrategy(headStyle, contentStyle))
|
||||||
// 关键:禁用EasyExcel自动创建表头行(后续手动控制行号)
|
// 关键:注册自定义处理器,提前处理标题、样式、合计等
|
||||||
.needHead(false)
|
.registerWriteHandler(new CustomExcelWriteHandler(totalActual, totalTax, totalTotal, processedList.size()))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// 2. 先获取Workbook和Sheet,手动创建大标题行(行0),此时行未刷盘
|
// 3. 配置 Sheet(数据从第2行开始,第0行是大标题,第1行是表头)
|
||||||
Workbook workbook = (Workbook) writer.writeContext().writeWorkbookHolder().getWorkbook();
|
|
||||||
Sheet sheet = workbook.getSheetAt(0);
|
|
||||||
if (sheet == null) {
|
|
||||||
sheet = workbook.createSheet("劳务费明细");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. 手动创建行0(大标题行),此时行在内存中,未刷盘
|
|
||||||
Row titleRow = sheet.getRow(0);
|
|
||||||
if (titleRow == null) {
|
|
||||||
titleRow = sheet.createRow(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 合并大标题行(0行0列 到 0行最后一列)
|
|
||||||
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, head.size() - 1));
|
|
||||||
|
|
||||||
|
|
||||||
// 4. 构建WriteSheet:表头从行1开始,数据从行2开始(对应relativeHeadRowIndex(1))
|
|
||||||
WriteSheet writeSheet = EasyExcel.writerSheet("劳务费明细")
|
WriteSheet writeSheet = EasyExcel.writerSheet("劳务费明细")
|
||||||
.needHead(true) // 重新开启表头,表头写入行1
|
.needHead(true)
|
||||||
.relativeHeadRowIndex(1) // 数据从行2开始(表头行1 + 1)
|
.relativeHeadRowIndex(1) // 表头行是第1行,数据从第2行开始
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// 5. 最后写入数据(行号递增:行0→行1→行2+,无回头修改)
|
// 4. 先写数据(此时自定义处理器会在写入前后处理样式/标题/合计)
|
||||||
writer.write(processedList, writeSheet);
|
writer.write(processedList, writeSheet);
|
||||||
|
|
||||||
titleRow.setHeightInPoints(30); // 设置标题行高
|
// 5. 响应头配置(中文文件名编码)
|
||||||
Cell titleCell = titleRow.createCell(0);
|
|
||||||
titleCell.setCellValue("人工肝诊疗病例征集项目专家劳务费表");
|
|
||||||
CellStyle titleStyle = workbook.createCellStyle();
|
|
||||||
Font font = workbook.createFont();
|
|
||||||
font.setFontHeightInPoints((short) 16);
|
|
||||||
font.setBold(true);
|
|
||||||
titleStyle.setFont(font);
|
|
||||||
titleStyle.setAlignment(HorizontalAlignment.CENTER);
|
|
||||||
titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
|
|
||||||
titleStyle.setBorderRight(BorderStyle.THIN); // 最后一格加右边框
|
|
||||||
titleCell.setCellStyle(titleStyle);
|
|
||||||
|
|
||||||
// === 设置行高 ===
|
|
||||||
sheet.getRow(1).setHeightInPoints(25); // 表头行
|
|
||||||
for (int i = 2; i <= processedList.size() + 2; i++) {
|
|
||||||
Row row = sheet.getRow(i);
|
|
||||||
if (row != null) {
|
|
||||||
row.setHeightInPoints(22);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// === 设置列宽 ===
|
|
||||||
int[] columnWidths = {
|
|
||||||
6, 25, 15, 15, 25, 10, 10, 30, 8, 8, 30, 25, 30, 15
|
|
||||||
};
|
|
||||||
for (int i = 0; i < columnWidths.length; i++) {
|
|
||||||
sheet.setColumnWidth(i, columnWidths[i] * 256); // 乘 256 为 Excel 单位
|
|
||||||
}
|
|
||||||
|
|
||||||
// 写合计行
|
|
||||||
int totalRowIndex = processedList.size() + 2; // +1是数据从第3行开始,+2是表头行数
|
|
||||||
Row totalRow = sheet.createRow(totalRowIndex);
|
|
||||||
totalRow.setHeightInPoints(22);
|
|
||||||
|
|
||||||
// 合计行样式(黑底白字)
|
|
||||||
CellStyle totalStyle = workbook.createCellStyle();
|
|
||||||
Font totalFont = workbook.createFont();
|
|
||||||
totalFont.setBold(true);
|
|
||||||
totalFont.setColor(IndexedColors.WHITE.getIndex());
|
|
||||||
totalStyle.setFont(totalFont);
|
|
||||||
totalStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
|
||||||
totalStyle.setAlignment(HorizontalAlignment.CENTER);
|
|
||||||
totalStyle.setVerticalAlignment(VerticalAlignment.CENTER);
|
|
||||||
totalStyle.setBorderTop(BorderStyle.THIN);
|
|
||||||
totalStyle.setBorderBottom(BorderStyle.THIN);
|
|
||||||
totalStyle.setBorderLeft(BorderStyle.THIN);
|
|
||||||
totalStyle.setBorderRight(BorderStyle.THIN);
|
|
||||||
|
|
||||||
// 合并前3列,写“合计”
|
|
||||||
sheet.addMergedRegion(new CellRangeAddress(totalRowIndex, totalRowIndex, 0, 5));
|
|
||||||
Cell cell0 = totalRow.createCell(0);
|
|
||||||
cell0.setCellValue("合计");
|
|
||||||
|
|
||||||
// 设置边框样式
|
|
||||||
CellStyle borderStyle = workbook.createCellStyle();
|
|
||||||
borderStyle.setBorderBottom(BorderStyle.THIN);
|
|
||||||
borderStyle.setBorderTop(BorderStyle.THIN);
|
|
||||||
borderStyle.setBorderLeft(BorderStyle.THIN);
|
|
||||||
borderStyle.setBorderRight(BorderStyle.THIN);
|
|
||||||
borderStyle.setAlignment(HorizontalAlignment.CENTER);
|
|
||||||
|
|
||||||
// 创建合计单元格并添加边框
|
|
||||||
for (int i = 0; i < head.size(); i++) {
|
|
||||||
Cell cell = totalRow.getCell(i);
|
|
||||||
if (cell == null) {
|
|
||||||
cell = totalRow.createCell(i);
|
|
||||||
}
|
|
||||||
cell.setCellStyle(borderStyle);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 实发(列 G = index 6)、个税(I = 8)、应发(J = 9)
|
|
||||||
totalRow.getCell(6).setCellValue(totalActual);
|
|
||||||
totalRow.getCell(8).setCellValue(totalTax);
|
|
||||||
totalRow.getCell(9).setCellValue(totalTotal);
|
|
||||||
|
|
||||||
// 6通知浏览器以附件的形式下载处理,设置返回头要注意文件名有中文
|
|
||||||
String fileName = URLEncoder.encode("病例数据", "UTF-8").replaceAll("\\+", "%20");
|
String fileName = URLEncoder.encode("病例数据", "UTF-8").replaceAll("\\+", "%20");
|
||||||
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
|
response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
|
||||||
response.setContentType("multipart/form-data");
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||||
response.setCharacterEncoding("utf-8");
|
response.setCharacterEncoding("utf-8");
|
||||||
|
|
||||||
|
// 6. 完成写入
|
||||||
writer.finish();
|
writer.finish();
|
||||||
//response.getOutputStream().flush();
|
|
||||||
outputStream.close();
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
// 补充:抛出异常让全局异常处理器处理,避免前端无响应
|
||||||
|
throw new RuntimeException("导出Excel失败:" + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,146 @@
|
|||||||
|
package net.lab1024.sa.admin.module.business.caseplatformcase.converter;
|
||||||
|
|
||||||
|
import com.alibaba.excel.metadata.Head;
|
||||||
|
import com.alibaba.excel.metadata.data.CellData;
|
||||||
|
import com.alibaba.excel.write.handler.WriteHandler;
|
||||||
|
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
|
||||||
|
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
|
||||||
|
import org.apache.poi.ss.usermodel.*;
|
||||||
|
import org.apache.poi.ss.util.CellRangeAddress;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CustomExcelWriteHandler implements WriteHandler {
|
||||||
|
private final double totalActual;
|
||||||
|
private final double totalTax;
|
||||||
|
private final double totalTotal;
|
||||||
|
private final int dataSize;
|
||||||
|
|
||||||
|
public CustomExcelWriteHandler(double totalActual, double totalTax, double totalTotal, int dataSize) {
|
||||||
|
this.totalActual = totalActual;
|
||||||
|
this.totalTax = totalTax;
|
||||||
|
this.totalTotal = totalTotal;
|
||||||
|
this.dataSize = dataSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
|
||||||
|
// 工作表创建后,先处理大标题、表头样式、列宽(此时还未写入数据,行未刷盘)
|
||||||
|
Workbook workbook = writeWorkbookHolder.getWorkbook();
|
||||||
|
Sheet sheet = writeSheetHolder.getSheet();
|
||||||
|
|
||||||
|
// 1. 处理大标题(第0行)
|
||||||
|
Row titleRow = sheet.createRow(0);
|
||||||
|
titleRow.setHeightInPoints(30);
|
||||||
|
Cell titleCell = titleRow.createCell(0);
|
||||||
|
titleCell.setCellValue("人工肝诊疗病例征集项目专家劳务费表");
|
||||||
|
// 合并大标题单元格(0行0列到0行最后一列)
|
||||||
|
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 13));
|
||||||
|
// 大标题样式
|
||||||
|
CellStyle titleStyle = workbook.createCellStyle();
|
||||||
|
Font titleFont = workbook.createFont();
|
||||||
|
titleFont.setFontHeightInPoints((short) 16);
|
||||||
|
titleFont.setBold(true);
|
||||||
|
titleStyle.setFont(titleFont);
|
||||||
|
titleStyle.setAlignment(HorizontalAlignment.CENTER);
|
||||||
|
titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||||
|
titleStyle.setBorderBottom(BorderStyle.THIN);
|
||||||
|
titleStyle.setBorderTop(BorderStyle.THIN);
|
||||||
|
titleStyle.setBorderLeft(BorderStyle.THIN);
|
||||||
|
titleStyle.setBorderRight(BorderStyle.THIN);
|
||||||
|
titleCell.setCellStyle(titleStyle);
|
||||||
|
|
||||||
|
// 2. 设置列宽
|
||||||
|
int[] columnWidths = {6, 25, 15, 15, 25, 10, 10, 30, 8, 8, 30, 25, 30, 15};
|
||||||
|
for (int i = 0; i < columnWidths.length; i++) {
|
||||||
|
sheet.setColumnWidth(i, columnWidths[i] * 256);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 预设置表头行(第1行)样式和行高
|
||||||
|
Row headRow = sheet.createRow(1);
|
||||||
|
headRow.setHeightInPoints(25);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void afterWorkbookDispose(WriteWorkbookHolder writeWorkbookHolder) {
|
||||||
|
// 数据写入完成后,处理合计行和数据行高(此时所有数据行已写入,但合计行是新创建的,未刷盘)
|
||||||
|
Workbook workbook = writeWorkbookHolder.getWorkbook();
|
||||||
|
Sheet sheet = workbook.getSheetAt(0);
|
||||||
|
|
||||||
|
// 1. 设置数据行行高(第2行到数据最后一行)
|
||||||
|
for (int i = 2; i <= dataSize + 1; i++) { // 数据从第2行开始,共dataSize行
|
||||||
|
Row row = sheet.getRow(i);
|
||||||
|
if (row != null) {
|
||||||
|
row.setHeightInPoints(22);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 处理合计行
|
||||||
|
int totalRowIndex = dataSize + 2; // 合计行在数据行最后一行的下一行
|
||||||
|
Row totalRow = sheet.createRow(totalRowIndex);
|
||||||
|
totalRow.setHeightInPoints(22);
|
||||||
|
|
||||||
|
// 合计行样式(黑底白字)
|
||||||
|
CellStyle totalStyle = workbook.createCellStyle();
|
||||||
|
Font totalFont = workbook.createFont();
|
||||||
|
totalFont.setBold(true);
|
||||||
|
totalFont.setColor(IndexedColors.WHITE.getIndex());
|
||||||
|
totalStyle.setFont(totalFont);
|
||||||
|
totalStyle.setFillForegroundColor(IndexedColors.BLACK.getIndex());
|
||||||
|
totalStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||||
|
totalStyle.setAlignment(HorizontalAlignment.CENTER);
|
||||||
|
totalStyle.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||||
|
totalStyle.setBorderTop(BorderStyle.THIN);
|
||||||
|
totalStyle.setBorderBottom(BorderStyle.THIN);
|
||||||
|
totalStyle.setBorderLeft(BorderStyle.THIN);
|
||||||
|
totalStyle.setBorderRight(BorderStyle.THIN);
|
||||||
|
|
||||||
|
// 合并前6列(0-5)写“合计”
|
||||||
|
sheet.addMergedRegion(new CellRangeAddress(totalRowIndex, totalRowIndex, 0, 5));
|
||||||
|
Cell totalCell = totalRow.createCell(0);
|
||||||
|
totalCell.setCellValue("合计");
|
||||||
|
totalCell.setCellStyle(totalStyle);
|
||||||
|
|
||||||
|
// 实发(6列)、个税(8列)、应发(9列)设置值和样式
|
||||||
|
Cell actualCell = totalRow.createCell(6);
|
||||||
|
actualCell.setCellValue(totalActual);
|
||||||
|
actualCell.setCellStyle(totalStyle);
|
||||||
|
|
||||||
|
Cell taxCell = totalRow.createCell(8);
|
||||||
|
taxCell.setCellValue(totalTax);
|
||||||
|
taxCell.setCellStyle(totalStyle);
|
||||||
|
|
||||||
|
Cell totalAmtCell = totalRow.createCell(9);
|
||||||
|
totalAmtCell.setCellValue(totalTotal);
|
||||||
|
totalAmtCell.setCellStyle(totalStyle);
|
||||||
|
|
||||||
|
// 其他列补充边框样式
|
||||||
|
CellStyle borderStyle = workbook.createCellStyle();
|
||||||
|
borderStyle.setBorderBottom(BorderStyle.THIN);
|
||||||
|
borderStyle.setBorderTop(BorderStyle.THIN);
|
||||||
|
borderStyle.setBorderLeft(BorderStyle.THIN);
|
||||||
|
borderStyle.setBorderRight(BorderStyle.THIN);
|
||||||
|
borderStyle.setAlignment(HorizontalAlignment.CENTER);
|
||||||
|
|
||||||
|
for (int i = 0; i < 14; i++) {
|
||||||
|
if (i == 0 || i == 6 || i == 8 || i == 9) {
|
||||||
|
continue; // 已设置样式的列跳过
|
||||||
|
}
|
||||||
|
Cell cell = totalRow.getCell(i);
|
||||||
|
if (cell == null) {
|
||||||
|
cell = totalRow.createCell(i);
|
||||||
|
}
|
||||||
|
cell.setCellStyle(borderStyle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 其他默认方法实现
|
||||||
|
public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {}
|
||||||
|
public void beforeWorkbookCreate(WriteWorkbookHolder writeWorkbookHolder) {}
|
||||||
|
public void beforeWorkbookDispose(WriteWorkbookHolder writeWorkbookHolder) {}
|
||||||
|
public void afterRowCreate(WriteSheetHolder writeSheetHolder, Row row, Integer relativeRowIndex, Boolean isHead) {}
|
||||||
|
public void afterRowDispose(WriteSheetHolder writeSheetHolder, Row row, Integer relativeRowIndex, Boolean isHead) {}
|
||||||
|
public void beforeRowCreate(WriteSheetHolder writeSheetHolder, Integer rowIndex, Integer relativeRowIndex, Boolean isHead) {}
|
||||||
|
public void beforeRowDispose(WriteSheetHolder writeSheetHolder, Row row, Integer relativeRowIndex, Boolean isHead) {}
|
||||||
|
public void afterCellCreate(WriteSheetHolder writeSheetHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {}
|
||||||
|
public void afterCellDispose(WriteSheetHolder writeSheetHolder, List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {}
|
||||||
|
public void beforeCellCreate(WriteSheetHolder writeSheetHolder, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user