EasyExcel导出excel,主标题、一个sheet多个table

使用阿里的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测试

好的,您可以使用Java中的ZipOutputStream类来实现压缩多个Excel文件。以下是一个简单的示例代码: ```java import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.metadata.Sheet; import com.alibaba.excel.metadata.Table; import com.alibaba.excel.support.ExcelTypeEnum; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; import java.io.*; import java.util.ArrayList; import java.util.List; public class ExportExcel { public static void main(String[] args) throws IOException { // 创建多个Excel文件 List<File> fileList = createExcelFiles(); // 创建压缩包文件 File zipFile = new File("excel_files.zip"); ZipArchiveOutputStream zipOutputStream = new ZipArchiveOutputStream(zipFile); zipOutputStream.setMethod(ZipArchiveOutputStream.DEFLATED); // 将多个Excel文件压缩到压缩包中 for (File file : fileList) { ZipArchiveEntry entry = new ZipArchiveEntry(file.getName()); entry.setSize(file.length()); zipOutputStream.putArchiveEntry(entry); FileInputStream fis = new FileInputStream(file); byte[] buffer = new byte[1024]; int len; while ((len = fis.read(buffer)) > 0) { zipOutputStream.write(buffer, 0, len); } fis.close(); zipOutputStream.closeArchiveEntry(); } // 关闭ZipOutputStream流 zipOutputStream.finish(); zipOutputStream.close(); // 删除临时Excel文件 for (File file : fileList) { file.delete(); } } private static List<File> createExcelFiles() throws FileNotFoundException { List<File> fileList = new ArrayList<>(); for (int i = 1; i <= 3; i++) { // 创建Excel文件 File file = new File("excel_" + i + ".xlsx"); OutputStream out = new FileOutputStream(file); // EasyExcel导出数据 ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX); Sheet sheet = new Sheet(1, 0); sheet.setSheetName("Sheet1"); Table table = new Table(1); List<List<String>> data = new ArrayList<>(); for (int j = 1; j <= 10; j++) { List<String> row = new ArrayList<>(); row.add("Data" + j); data.add(row); } table.setData(data); writer.write0(table, sheet); writer.finish(); // 添加Excel文件到列表中 fileList.add(file); } return fileList; } } ``` 在上面的代码中,我们首先创建了3个Excel文件,然后将它们压缩到一个名为“excel\_files.zip”的压缩包中。最后,我们删除了临时的Excel文件。注意,我们使用了Apache Commons Compress库来实现压缩操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值