使用阿里的EasyExcel导出Excel,一个sheet中包括如下内容:
1. 第一行展示主标题;
2. 一个sheet多个table
如下图所示:
1.pom.xml
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel-core</artifactId>
<version>3.3.2</version>
</dependency>
2. 导出的实体类
import java.math.BigDecimal;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentFontStyle;
import com.alibaba.excel.annotation.write.style.ContentStyle;
import com.alibaba.excel.annotation.write.style.HeadFontStyle;
import com.alibaba.excel.annotation.write.style.HeadStyle;
import com.alibaba.excel.enums.poi.BorderStyleEnum;
import com.alibaba.excel.enums.poi.FillPatternTypeEnum;
import com.alibaba.excel.enums.poi.HorizontalAlignmentEnum;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
/**
* 导出实施进度报表
*
* @author
* @date 2024/9/14 星期六
* @since JDK 17
*/
@Data
@EqualsAndHashCode(callSuper = false)
@ToString(callSuper = true)
public class ImplProgressReportExportVo {
/** 序号 */
// 这一列 每隔2行 合并单元格
// @ContentLoopMerge(eachRow = 2)
@ExcelProperty(value = "序号", index = 0)
@HeadFontStyle(fontHeightInPoints = 10) // 字体大小
@ColumnWidth(10)
// HorizontalAlignmentEnum.CENTER 居中
// FillPatternTypeEnum.SOLID_FOREGROUND : 充满
// fillForegroundColor 见 https://www.cnblogs.com/hezemin/p/17272591.html
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 1)
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND,
fillForegroundColor = 1, borderRight = BorderStyleEnum.THIN, borderBottom = BorderStyleEnum.THIN)
@ContentFontStyle(fontHeightInPoints = 10) // 字体大小
private String number;
@ExcelProperty(value = "项目", index = 1)
@HeadFontStyle(fontHeightInPoints = 10) // 字体大小
@ColumnWidth(20)
// HorizontalAlignmentEnum.CENTER 居中
// FillPatternTypeEnum.SOLID_FOREGROUND : 充满
// fillForegroundColor 见 https://www.cnblogs.com/hezemin/p/17272591.html
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 1)
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND,
fillForegroundColor = 1, borderRight = BorderStyleEnum.THIN, borderBottom = BorderStyleEnum.THIN)
@ContentFontStyle(fontHeightInPoints = 10) // 字体大小
private String fundName;
/** 单位 */
@ExcelProperty(value = "单位", index = 2)
@HeadFontStyle(fontHeightInPoints = 10) // 字体大小
@ColumnWidth(10)
// HorizontalAlignmentEnum.CENTER 居中
// FillPatternTypeEnum.SOLID_FOREGROUND : 充满
// fillForegroundColor 见 https://www.cnblogs.com/hezemin/p/17272591.html
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 1)
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND,
fillForegroundColor = 1, borderRight = BorderStyleEnum.THIN, borderBottom = BorderStyleEnum.THIN)
@ContentFontStyle(fontHeightInPoints = 10) // 字体大小
private String unit;
/** 初步设计指标/投资(设计单位填报) */
@ExcelProperty(value = "初步设计指标", index = 3)
@HeadFontStyle(fontHeightInPoints = 10) // 字体大小
@ColumnWidth(12)
// HorizontalAlignmentEnum.CENTER 居中
// FillPatternTypeEnum.SOLID_FOREGROUND : 充满
// fillForegroundColor 见 https://www.cnblogs.com/hezemin/p/17272591.html
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 42)
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND,
fillForegroundColor = 42, borderRight = BorderStyleEnum.THIN, borderBottom = BorderStyleEnum.THIN)
@ContentFontStyle(fontHeightInPoints = 10) // 字体大小
private BigDecimal totalPlan;
/** 实施合计(当月完成指标) */
@ExcelProperty(value = { "实施合计", "当月完成指标" }, index = 4)
@HeadFontStyle(fontHeightInPoints = 10) // 字体大小
@ColumnWidth(12)
// HorizontalAlignmentEnum.CENTER 居中
// FillPatternTypeEnum.SOLID_FOREGROUND : 充满
// fillForegroundColor 见 https://www.cnblogs.com/hezemin/p/17272591.html
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 1)
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND,
fillForegroundColor = 1, borderRight = BorderStyleEnum.THIN, borderBottom = BorderStyleEnum.THIN)
@ContentFontStyle(fontHeightInPoints = 10) // 字体大小
private BigDecimal implCurMonthComplete;
/** 实施合计(累计完成指标) */
@ExcelProperty(value = { "实施合计", "累计完成指标" }, index = 5)
@HeadFontStyle(fontHeightInPoints = 10) // 字体大小
@ColumnWidth(12)
// HorizontalAlignmentEnum.CENTER 居中
// FillPatternTypeEnum.SOLID_FOREGROUND : 充满
// fillForegroundColor 见 https://www.cnblogs.com/hezemin/p/17272591.html
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 1)
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND,
fillForegroundColor = 1, borderRight = BorderStyleEnum.THIN, borderBottom = BorderStyleEnum.THIN)
@ContentFontStyle(fontHeightInPoints = 10) // 字体大小
private BigDecimal implTotalComplete;
/** 环北公司(当月完成指标) */
@ExcelProperty(value = { "环北公司", "当月完成指标" }, index = 6)
@HeadFontStyle(fontHeightInPoints = 10) // 字体大小
@ColumnWidth(12)
// HorizontalAlignmentEnum.CENTER 居中
// FillPatternTypeEnum.SOLID_FOREGROUND : 充满
// fillForegroundColor 见 https://www.cnblogs.com/hezemin/p/17272591.html
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 47)
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND,
fillForegroundColor = 47, borderRight = BorderStyleEnum.THIN, borderBottom = BorderStyleEnum.THIN)
@ContentFontStyle(fontHeightInPoints = 10) // 字体大小
private BigDecimal hbCurMonthComplete;
/** 环北公司(累计完成指标) */
@ExcelProperty(value = { "环北公司", "累计完成指标" }, index = 7)
@HeadFontStyle(fontHeightInPoints = 10) // 字体大小
@ColumnWidth(12)
// HorizontalAlignmentEnum.CENTER 居中
// FillPatternTypeEnum.SOLID_FOREGROUND : 充满
// fillForegroundColor 见 https://www.cnblogs.com/hezemin/p/17272591.html
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 47)
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND,
fillForegroundColor = 47, borderRight = BorderStyleEnum.THIN, borderBottom = BorderStyleEnum.THIN)
@ContentFontStyle(fontHeightInPoints = 10) // 字体大小
private BigDecimal hbTotalComplete;
/** 南宁市(当月完成指标) */
@ExcelProperty(value = { "南宁市", "当月完成指标" }, index = 8)
@HeadFontStyle(fontHeightInPoints = 10) // 字体大小
@ColumnWidth(12)
// HorizontalAlignmentEnum.CENTER 居中
// FillPatternTypeEnum.SOLID_FOREGROUND : 充满
// fillForegroundColor 见 https://www.cnblogs.com/hezemin/p/17272591.html
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 31)
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND,
fillForegroundColor = 31, borderRight = BorderStyleEnum.THIN, borderBottom = BorderStyleEnum.THIN)
@ContentFontStyle(fontHeightInPoints = 10) // 字体大小
private BigDecimal nanNingCurMonthComplete;
/** 南宁市(累计完成指标) */
@ExcelProperty(value = { "南宁市", "累计完成指标" }, index = 9)
@HeadFontStyle(fontHeightInPoints = 10) // 字体大小
@ColumnWidth(12)
// HorizontalAlignmentEnum.CENTER 居中
// FillPatternTypeEnum.SOLID_FOREGROUND : 充满
// fillForegroundColor 见 https://www.cnblogs.com/hezemin/p/17272591.html
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 31)
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND,
fillForegroundColor = 31, borderRight = BorderStyleEnum.THIN, borderBottom = BorderStyleEnum.THIN)
@ContentFontStyle(fontHeightInPoints = 10) // 字体大小
private BigDecimal nanNingTotalComplete;
/** 北海市(当月完成指标) */
@ExcelProperty(value = { "北海市", "当月完成指标" }, index = 10)
@HeadFontStyle(fontHeightInPoints = 10) // 字体大小
@ColumnWidth(12)
// HorizontalAlignmentEnum.CENTER 居中
// FillPatternTypeEnum.SOLID_FOREGROUND : 充满
// fillForegroundColor 见 https://www.cnblogs.com/hezemin/p/17272591.html
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 31)
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND,
fillForegroundColor = 31, borderRight = BorderStyleEnum.THIN, borderBottom = BorderStyleEnum.THIN)
@ContentFontStyle(fontHeightInPoints = 10) // 字体大小
private BigDecimal beiHaiCurMonthComplete;
/** 北海市(累计完成指标) */
@ExcelProperty(value = { "北海市", "累计完成指标" }, index = 11)
@HeadFontStyle(fontHeightInPoints = 10) // 字体大小
@ColumnWidth(12)
// HorizontalAlignmentEnum.CENTER 居中
// FillPatternTypeEnum.SOLID_FOREGROUND : 充满
// fillForegroundColor 见 https://www.cnblogs.com/hezemin/p/17272591.html
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 31)
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND,
fillForegroundColor = 31, borderRight = BorderStyleEnum.THIN, borderBottom = BorderStyleEnum.THIN)
@ContentFontStyle(fontHeightInPoints = 10) // 字体大小
private BigDecimal beiHaiTotalComplete;
/** 防城港市(当月完成指标) */
@ExcelProperty(value = { "防城港市", "当月完成指标" }, index = 12)
@HeadFontStyle(fontHeightInPoints = 10) // 字体大小
@ColumnWidth(12)
// HorizontalAlignmentEnum.CENTER 居中
// FillPatternTypeEnum.SOLID_FOREGROUND : 充满
// fillForegroundColor 见 https://www.cnblogs.com/hezemin/p/17272591.html
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 31)
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND,
fillForegroundColor = 31, borderRight = BorderStyleEnum.THIN, borderBottom = BorderStyleEnum.THIN)
@ContentFontStyle(fontHeightInPoints = 10) // 字体大小
private BigDecimal fcgCurMonthComplete;
/** 防城港市(累计完成指标) */
@ExcelProperty(value = { "防城港市", "累计完成指标" }, index = 13)
@HeadFontStyle(fontHeightInPoints = 10) // 字体大小
@ColumnWidth(12)
// HorizontalAlignmentEnum.CENTER 居中
// FillPatternTypeEnum.SOLID_FOREGROUND : 充满
// fillForegroundColor 见 https://www.cnblogs.com/hezemin/p/17272591.html
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 31)
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND,
fillForegroundColor = 31, borderRight = BorderStyleEnum.THIN, borderBottom = BorderStyleEnum.THIN)
@ContentFontStyle(fontHeightInPoints = 10) // 字体大小
private BigDecimal fcgTotalComplete;
/** 钦州市(当月完成指标) */
@ExcelProperty(value = { "钦州市", "当月完成指标" }, index = 14)
@HeadFontStyle(fontHeightInPoints = 10) // 字体大小
@ColumnWidth(12)
// HorizontalAlignmentEnum.CENTER 居中
// FillPatternTypeEnum.SOLID_FOREGROUND : 充满
// fillForegroundColor 见 https://www.cnblogs.com/hezemin/p/17272591.html
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 31)
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND,
fillForegroundColor = 31, borderRight = BorderStyleEnum.THIN, borderBottom = BorderStyleEnum.THIN)
@ContentFontStyle(fontHeightInPoints = 10) // 字体大小
private BigDecimal qinZhouCurMonthComplete;
/** 钦州市(累计完成指标) */
@ExcelProperty(value = { "钦州市", "累计完成指标" }, index = 15)
@HeadFontStyle(fontHeightInPoints = 10) // 字体大小
@ColumnWidth(12)
// HorizontalAlignmentEnum.CENTER 居中
// FillPatternTypeEnum.SOLID_FOREGROUND : 充满
// fillForegroundColor 见 https://www.cnblogs.com/hezemin/p/17272591.html
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 31)
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND,
fillForegroundColor = 31, borderRight = BorderStyleEnum.THIN, borderBottom = BorderStyleEnum.THIN)
@ContentFontStyle(fontHeightInPoints = 10) // 字体大小
private BigDecimal qinZhouTotalComplete;
/** 玉林市(当月完成指标) */
@ExcelProperty(value = { "玉林市", "当月完成指标" }, index = 16)
@HeadFontStyle(fontHeightInPoints = 10) // 字体大小
@ColumnWidth(12)
// HorizontalAlignmentEnum.CENTER 居中
// FillPatternTypeEnum.SOLID_FOREGROUND : 充满
// fillForegroundColor 见 https://www.cnblogs.com/hezemin/p/17272591.html
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 31)
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND,
fillForegroundColor = 31, borderRight = BorderStyleEnum.THIN, borderBottom = BorderStyleEnum.THIN)
@ContentFontStyle(fontHeightInPoints = 10) // 字体大小
private BigDecimal yuLinCurMonthComplete;
/** 玉林市(累计完成指标) */
@ExcelProperty(value = { "玉林市", "累计完成指标" }, index = 17)
@HeadFontStyle(fontHeightInPoints = 10) // 字体大小
@ColumnWidth(12)
// HorizontalAlignmentEnum.CENTER 居中
// FillPatternTypeEnum.SOLID_FOREGROUND : 充满
// fillForegroundColor 见 https://www.cnblogs.com/hezemin/p/17272591.html
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 31)
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND,
fillForegroundColor = 31, borderRight = BorderStyleEnum.THIN, borderBottom = BorderStyleEnum.THIN)
@ContentFontStyle(fontHeightInPoints = 10) // 字体大小
private BigDecimal yuLinTotalComplete;
}
3. 主标题行高
import org.apache.poi.ss.usermodel.Row;
import com.alibaba.excel.write.style.row.AbstractRowHeightStyleStrategy;
/**
* 实施进度报表 行高设置
* @author
* @date 2024/9/19 星期四
* @since JDK 17
*/
public class ImplProgressReportTitleRowHeightStyleStrategy extends AbstractRowHeightStyleStrategy {
@Override
protected void setHeadColumnHeight(Row row, int relativeRowIndex) {
// 设置主标题行高为 25.5
if(relativeRowIndex == 0){
// 25.5*20
row.setHeight((short) 510);
}
}
@Override
protected void setContentColumnHeight(Row row, int relativeRowIndex) {
// 设置主标题行高为 25.5
if(relativeRowIndex == 0){
// 25.5*20
row.setHeight((short) 510);
}
}
}
4. 主标题行样式
import java.awt.*;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.xssf.usermodel.DefaultIndexedColorMap;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.AbstractCellStyleStrategy;
/**
* 实施进度报表 主标题行样式
*
* @author
* @date 2024/9/19 星期四
* @since JDK 17
*/
public class ImplProgressReportTitleRowStyleStrategy extends AbstractCellStyleStrategy {
@Override
protected void setHeadCellStyle(CellWriteHandlerContext context) {
// 获取和创建CellStyle
WriteCellData<?> cellData = context.getFirstCellData();
CellStyle originCellStyle = cellData.getOriginCellStyle();
Cell cell = context.getCell();
if (originCellStyle == null) {
originCellStyle = context.getWriteWorkbookHolder().getWorkbook().createCellStyle();
}
// 设置背景颜色
((XSSFCellStyle) originCellStyle)
.setFillForegroundColor(new XSSFColor(Color.WHITE, new DefaultIndexedColorMap()));
// 背景色充满
originCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
originCellStyle.setWrapText(true);
// 重点!!!
// 由于在FillStyleCellWriteHandler,会把OriginCellStyle和WriteCellStyle合并,会已WriteCellStyle样式为主,所有必须把WriteCellStyle设置的背景色清空
// 具体合并规则请看WriteWorkbookHolder.createCellStyle方法
WriteCellStyle writeCellStyle = cellData.getWriteCellStyle();
writeCellStyle.setFillForegroundColor(null);
// 重点!!! 必须设置OriginCellStyle
cellData.setOriginCellStyle(originCellStyle);
// 字体
WriteFont headWriteFont = new WriteFont();
if (cell.getRowIndex() == 0) {
headWriteFont.setFontName("方正小标宋_GBK");
// 字体颜色
headWriteFont.setColor(IndexedColors.BLACK.getIndex());
// 字体大小
headWriteFont.setFontHeightInPoints((short) 20);
}
if (0 == context.getRowIndex()) {
writeCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
}
// else {
// writeCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
// }
cellData.getWriteCellStyle().setWriteFont(headWriteFont);
}
// 设置填充数据样式
@Override
protected void setContentCellStyle(CellWriteHandlerContext context) {
// WriteFont contentWriteFont = new WriteFont();
// contentWriteFont.setFontName("方正小标宋_GBK");
// contentWriteFont.setFontHeightInPoints((short) 20);
//
// WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
// // 设置数据填充后的实线边框
// contentWriteCellStyle.setWriteFont(contentWriteFont);
// // 前景色充满
// contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
// // 前景色为白色,见:https://www.cnblogs.com/hezemin/p/17272591.html
// contentWriteCellStyle.setFillForegroundColor((short) 9);
// contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
// contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
// contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
// contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);
// DataFormatData dataFormatData = new DataFormatData();
// dataFormatData.setIndex((short) 49);
// contentWriteCellStyle.setDataFormatData(dataFormatData);
// contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
// WriteCellData<?> cellData = context.getFirstCellData();
// WriteCellStyle.merge(contentWriteCellStyle, cellData.getOrCreateStyle());
}
}
5. controller
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.merge.OnceAbsoluteMergeStrategy;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.WriteTable;
import com.alibaba.fastjson.JSON;
import com.jeesite.common.service.ServiceException;
import com.jeesite.modules.common.base.ResponseApiData;
import com.jeesite.modules.migrate.prjbid.excel.handler.ImplProgressReportTitleRowHeightStyleStrategy;
import com.jeesite.modules.migrate.prjbid.excel.handler.ImplProgressReportTitleRowStyleStrategy;
import com.jeesite.modules.migrate.prjbid.excel.vo.ImplProgressReportExportVo;
import com.jeesite.modules.migrate.prjbid.reponse.ImplProgressReportResponse;
import com.jeesite.modules.migrate.prjbid.reponse.MigrateBidFillStatResponse;
import com.jeesite.modules.migrate.prjbid.request.ImplProgressReportRequest;
import com.jeesite.modules.migrate.prjbid.request.MigrateBidFillStatRequest;
import com.jeesite.modules.migrate.prjbid.service.ImplProgressReportService;
import com.jeesite.modules.migrate.prjbid.service.MigrateBidFillStatService;
import cn.hutool.core.io.IoUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
/**
* xxx统计 API接口
*
* @author
* @date 2024/8/26
* @since JDK 17
*/
@Slf4j
@Api(tags = "xxx统计 API接口")
@RestController
@RequestMapping(value = "/migrate/prjbid/fill")
public class MigrateBidFillStatController {
@ApiOperation(value = "导出实施进度报表")
@PostMapping("/export/implProgressReport")
public void implProgressReportExport(HttpServletResponse response, @RequestBody ImplProgressReportRequest request) {
/* 参考:https://blog.csdn.net/qq_43932985/article/details/141644977 */
log.info("导出实施进度报表-开始.请求参数:{}", JSON.toJSONString(request));
ServletOutputStream os = null;
ExcelWriter excelWriter = null;
try {
this.setExcelResponseProp(response, "实施进度报表");
/* 第一个报表 */
ImplProgressReportExportVo vo1 = new ImplProgressReportExportVo();
vo1.setNumber("一");
vo1.setFundName("土地");
vo1.setUnit("亩");
vo1.setTotalPlan(new BigDecimal("31751.62"));
vo1.setImplCurMonthComplete(new BigDecimal("391.46"));
vo1.setImplTotalComplete(new BigDecimal("3185.2"));
//vo1.setHbCurMonthComplete(BigDecimal.ZERO);
//vo1.setHbTotalComplete(BigDecimal.ZERO);
vo1.setNanNingCurMonthComplete(new BigDecimal("167.7"));
vo1.setNanNingTotalComplete(new BigDecimal("620.31"));
vo1.setBeiHaiCurMonthComplete(new BigDecimal("45.22"));
vo1.setBeiHaiTotalComplete(new BigDecimal("437.43"));
vo1.setFcgCurMonthComplete(new BigDecimal("7.53"));
vo1.setFcgTotalComplete(new BigDecimal("101.98"));
vo1.setQinZhouCurMonthComplete(new BigDecimal("171.01"));
vo1.setQinZhouTotalComplete(new BigDecimal("1581.62"));
//vo1.setYuLinCurMonthComplete(BigDecimal.ZERO);
vo1.setYuLinTotalComplete(new BigDecimal("443.86"));
ImplProgressReportExportVo vo2 = new ImplProgressReportExportVo();
vo2.setNumber("1");
vo2.setFundName("永久用地");
vo2.setUnit("亩");
vo2.setTotalPlan(new BigDecimal("2605.88"));
// vo2.setImplCurMonthComplete(BigDecimal.ZERO);
// vo2.setImplTotalComplete(BigDecimal.ZERO);
// vo2.setHbCurMonthComplete(BigDecimal.ZERO);
// vo2.setHbTotalComplete(BigDecimal.ZERO);
// vo2.setNanNingCurMonthComplete(BigDecimal.ZERO);
// vo2.setNanNingTotalComplete(BigDecimal.ZERO);
// vo2.setBeiHaiCurMonthComplete(BigDecimal.ZERO);
// vo2.setBeiHaiTotalComplete(BigDecimal.ZERO);
// vo2.setFcgCurMonthComplete(BigDecimal.ZERO);
// vo2.setFcgTotalComplete(BigDecimal.ZERO);
// vo2.setQinZhouCurMonthComplete(BigDecimal.ZERO);
// vo2.setQinZhouTotalComplete(BigDecimal.ZERO);
// vo2.setYuLinCurMonthComplete(BigDecimal.ZERO);
// vo2.setYuLinTotalComplete(BigDecimal.ZERO);
ImplProgressReportExportVo vo3 = new ImplProgressReportExportVo();
vo3.setNumber("2");
vo3.setFundName("临时用地");
vo3.setUnit("亩");
vo3.setTotalPlan(new BigDecimal("29145.74"));
vo3.setImplCurMonthComplete(new BigDecimal("391.46"));
vo3.setImplTotalComplete(new BigDecimal("3185.2"));
//vo3.setHbCurMonthComplete(BigDecimal.ZERO);
//vo3.setHbTotalComplete(BigDecimal.ZERO);
vo3.setNanNingCurMonthComplete(new BigDecimal("167.7"));
vo3.setNanNingTotalComplete(new BigDecimal("620.31"));
vo3.setBeiHaiCurMonthComplete(new BigDecimal("45.22"));
vo3.setBeiHaiTotalComplete(new BigDecimal("437.43"));
vo3.setFcgCurMonthComplete(new BigDecimal("7.53"));
vo3.setFcgTotalComplete(new BigDecimal("101.98"));
vo3.setQinZhouCurMonthComplete(new BigDecimal("171.01"));
vo3.setQinZhouTotalComplete(new BigDecimal("1581.62"));
//vo3.setYuLinCurMonthComplete(BigDecimal.ZERO);
vo3.setYuLinTotalComplete(new BigDecimal("443.86"));
os = response.getOutputStream();
// EasyExcel.write(os).head(ImplProgressReportExportVo.class).excelType(ExcelTypeEnum.XLSX)
// .registerWriteHandler(new ImplProgressReportCellWriteHandler(2, 2, new int[]{
// // 需要合并部门列、部门描述列、工资范围列
// 0, 1, 2}, ((cur, pre) -> {
// // 部门名称相同 && 工资范围相同才需要合并
// String curDept = cur.getCell(0).getStringCellValue();
// String preDept = pre.getCell(0).getStringCellValue();
// String curSalaryRange = cur.getCell(2).getStringCellValue();
// String preSalaryRange = pre.getCell(2).getStringCellValue();
// return curDept.equals(preDept) && curSalaryRange.equals(preSalaryRange) ? true : false;
// }))).sheet("实施进度报表").doWrite(Arrays.asList(vo1, vo2, vo3));
List<ImplProgressReportExportVo> firstList = new ArrayList<>(Arrays.asList(vo1, vo2, vo3));
/* 第二个报表 */
ImplProgressReportExportVo vo4 = new ImplProgressReportExportVo();
vo4.setNumber("第一部分");
vo4.setFundName("农村部分补偿费");
vo4.setUnit("万元");
vo4.setTotalPlan(new BigDecimal("98257.23"));
vo4.setImplCurMonthComplete(new BigDecimal("1561.39"));
vo4.setImplTotalComplete(new BigDecimal("5073.29"));
//vo4.setHbCurMonthComplete(BigDecimal.ZERO);
//vo4.setHbTotalComplete(BigDecimal.ZERO);
vo4.setNanNingCurMonthComplete(new BigDecimal("1187.82"));
vo4.setNanNingTotalComplete(new BigDecimal("1825.92"));
vo4.setBeiHaiCurMonthComplete(new BigDecimal("167.54"));
vo4.setBeiHaiTotalComplete(new BigDecimal("780.02"));
vo4.setFcgCurMonthComplete(new BigDecimal("3.38"));
vo4.setFcgTotalComplete(new BigDecimal("96.55"));
vo4.setQinZhouCurMonthComplete(new BigDecimal("202.65"));
vo4.setQinZhouTotalComplete(new BigDecimal("1889.58"));
//vo4.setYuLinCurMonthComplete(BigDecimal.ZERO);
vo4.setYuLinTotalComplete(new BigDecimal("481.22"));
ImplProgressReportExportVo vo5 = new ImplProgressReportExportVo();
vo5.setNumber("一");
vo5.setFundName("征地补偿费及青苗、林木补偿费");
vo5.setUnit("万元");
vo5.setTotalPlan(new BigDecimal("90672.63"));
vo5.setImplCurMonthComplete(new BigDecimal("1464.47"));
vo5.setImplTotalComplete(new BigDecimal("4854.12"));
// vo5.setHbCurMonthComplete(BigDecimal.ZERO);
// vo5.setHbTotalComplete(BigDecimal.ZERO);
vo5.setNanNingCurMonthComplete(BigDecimal.ZERO);
vo5.setNanNingTotalComplete(new BigDecimal("4854.12"));
vo5.setBeiHaiCurMonthComplete(new BigDecimal("167.21"));
vo5.setBeiHaiTotalComplete(new BigDecimal("684.13"));
vo5.setFcgCurMonthComplete(new BigDecimal("3.38"));
vo5.setFcgTotalComplete(new BigDecimal("96.2"));
vo5.setQinZhouCurMonthComplete(new BigDecimal("111.55"));
vo5.setQinZhouTotalComplete(new BigDecimal("1780.64"));
// vo5.setYuLinCurMonthComplete(BigDecimal.ZERO);
vo5.setYuLinTotalComplete(new BigDecimal("472.72"));
ImplProgressReportExportVo vo6 = new ImplProgressReportExportVo();
vo6.setNumber("二");
vo6.setFundName("移民搬迁及房屋设施补偿费");
vo6.setUnit("万元");
vo6.setTotalPlan(new BigDecimal("1873.8"));
vo6.setImplCurMonthComplete(new BigDecimal("91.68"));
vo6.setImplTotalComplete(new BigDecimal("157.15"));
//vo6.setHbCurMonthComplete(BigDecimal.ZERO);
//vo6.setHbTotalComplete(BigDecimal.ZERO);
vo6.setNanNingCurMonthComplete(new BigDecimal("0.25"));
vo6.setNanNingTotalComplete(new BigDecimal("0.25"));
vo6.setBeiHaiCurMonthComplete(new BigDecimal("0.33"));
vo6.setBeiHaiTotalComplete(new BigDecimal("52.96"));
// vo6.setFcgCurMonthComplete(new BigDecimal("7.53"));
// vo6.setFcgTotalComplete(new BigDecimal("101.98"));
vo6.setQinZhouCurMonthComplete(new BigDecimal("91.10"));
vo6.setQinZhouTotalComplete(new BigDecimal("95.44"));
//vo6.setYuLinCurMonthComplete(BigDecimal.ZERO);
vo6.setYuLinTotalComplete(new BigDecimal("8.50"));
List<ImplProgressReportExportVo> secondList = new ArrayList<>(Arrays.asList(vo4, vo5, vo6));
excelWriter = EasyExcel.write(os).build();
// 把sheet设置为不需要头 不然会输出sheet的头 这样看起来第一个table 就有2个头了
WriteSheet writeSheet = EasyExcel.writerSheet().needHead(Boolean.FALSE).sheetName("实施进度报表").build();
// 主标题
List<String> title = Arrays.asList("xxx报表");
List<List<String>> titleHead = new ArrayList<>(Arrays.asList(title));
// 合并主标题行:将第1行的第1-18列合并
OnceAbsoluteMergeStrategy absoluteMergeStrategy = new OnceAbsoluteMergeStrategy(0, 0, 0, 17);
// 主标题
WriteTable titleTable = EasyExcel.writerTable(0)
.head(titleHead)
.needHead(Boolean.TRUE)
// 自动合并头,头中相同的字段上下左右都会去尝试匹配
.automaticMergeHead(Boolean.TRUE)
.registerWriteHandler(absoluteMergeStrategy)
// 行高
.registerWriteHandler(new ImplProgressReportTitleRowHeightStyleStrategy())
// 样式,参考:https://blog.csdn.net/weixin_44077141/article/details/139008521
.registerWriteHandler(new ImplProgressReportTitleRowStyleStrategy())
.build();
// 这里必须指定需要头,table 会继承sheet的配置,sheet配置了不需要,table 默认也是不需要
WriteTable writeTable1 = EasyExcel.writerTable(1)
.head(ImplProgressReportExportVo.class)
.needHead(Boolean.TRUE)
.build();
// 第二个对象 读取对象的excel实体类中的标题
WriteTable writeTable2 = EasyExcel.writerTable(2)
.head(ImplProgressReportExportVo.class)
.needHead(Boolean.TRUE)
// 和第一个报表间隔两行
.relativeHeadRowIndex(2)
.build();
// 写入主标题
excelWriter.write(new ArrayList<>(), writeSheet, titleTable);
// 第一次写入会创建头
excelWriter.write(firstList, writeSheet, writeTable1);
// 第二次写如也会创建头,然后在第一次的后面写入数据
excelWriter.write(secondList, writeSheet, writeTable2);
} catch (Exception e) {
log.error(String.format("导出实施进度报表-失败.请求参数:%s", JSON.toJSONString(request)), e);
} finally {
IoUtil.close(excelWriter);
IoUtil.close(os);
}
}
/**
* 设置响应结果
*
* @param response 响应结果对象
* @param rawFileName 文件名
* @throws UnsupportedEncodingException 不支持编码异常
*/
private void setExcelResponseProp(HttpServletResponse response, String rawFileName) throws UnsupportedEncodingException {
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode(rawFileName, "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
}
}
6.postman测试