easy-excel复杂格式

1.支持easy-excel模板与不同列表循环打印,合并表头,背景色;

2.支持excel的高度自适应

3. 支持多sheet页面模板打印;

代码如下

    @Test
    public void compositeFill1() {
        // 模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替
        // {} 代表普通变量 {.} 代表是list的变量 {前缀.} 前缀可以区分不同的list
        String templateFileName =
            TestFileUtil.getPath() + "demo" + File.separator + "fill" + File.separator
                + "composite_2.xlsx";

        String fileName =
            TestFileUtil.getPath() + "compositeFill" + System.currentTimeMillis() + ".xlsx";
        ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build();
//        WriteSheet writeSheet = EasyExcel.writerSheet().build();
        FillConfig fillConfig = FillConfig.builder().direction(WriteDirectionEnum.HORIZONTAL)
            .build();

        excelWriter.write(Collections.singletonList(new TargetHeader()), EasyExcel.writerSheet().head(TargetHeader.class)
            .needHead(Boolean.FALSE)
            .build());
        clear(excelWriter);
        excelWriter.write(Collections.singletonList(new TargetData()),
            EasyExcel.writerSheet().head(TargetData.class).needHead(Boolean.FALSE)
                .build(),
            EasyExcel.writerTable(1).needHead(Boolean.FALSE).build());
        clear(excelWriter);

        WriteSheet writeSheet2 = EasyExcel.writerSheet().needHead(Boolean.FALSE)
            .head(QuestionHeader.class)
            .build();
        excelWriter.write(Collections.singletonList(new QuestionHeader()), writeSheet2);
        clear(excelWriter);
        excelWriter.write(asList(new QuestionData(),new QuestionData(),new QuestionData(),new QuestionData()), EasyExcel.writerSheet().needHead(Boolean.FALSE)
            .head(QuestionData.class)
            .build());
//        excelWriter.finish();

        clear(excelWriter);

        Map map = new HashMap();
        map.put("name", "河南利丰机构");
        excelWriter.fill(map, EasyExcel.writerSheet().build());
        excelWriter.finish();
        // 别忘记关闭流
    }


    //清空easy-excel缓存的样式
    private void clear(ExcelWriter excelWriter) {
        excelWriter.writeContext().writeWorkbookHolder().getHasBeenInitializedSheetIndexMap()
            .clear();
        excelWriter.writeContext().writeWorkbookHolder().getHasBeenInitializedSheetNameMap()
            .clear();
//        excelWriter.writeContext().writeWorkbookHolder().writeHandlerMap().clear();
    }
package com.alibaba.easyexcel.test.temp;

import static org.apache.poi.ss.usermodel.BorderStyle.THIN;

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ContentLoopMerge;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.ContentStyle;
import lombok.Data;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;

/**
 * @author Jiaju Zhuang
 */
@Data
@ContentStyle( borderRight = THIN,borderLeft =  THIN, borderTop = THIN, borderBottom = THIN, fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 1, horizontalAlignment = HorizontalAlignment.CENTER, wrapped = true)
@ContentRowHeight(45)
public class QuestionData {

    //    @ContentLoopMerge(eachRow = 1, columnExtend = 1)
    @ExcelProperty(index = 0)
    private String no = "1";

    @ContentLoopMerge(eachRow = 1, columnExtend = 4)
    @ExcelProperty(index = 1)
    @ContentStyle(  borderTop = THIN, borderBottom = THIN, fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 1, horizontalAlignment = HorizontalAlignment.CENTER, wrapped = true)
    private String path = "企业股权结构和实际控制人情况";
    @ContentLoopMerge(eachRow = 1, columnExtend = 9)
    @ExcelProperty(index = 5)
    private String content = "是否存在控股股东和如有,请说明具体情况。";
    @ExcelProperty(index = 14)
    private String flag = "";

    @ExcelProperty(index = 2)
    private String p2;
    @ExcelProperty(index = 3)
    private String p3;
    @ExcelProperty(index = 4)
    private String p4;
    @ExcelProperty(index = 6)
    private String p6;
    @ExcelProperty(index = 7)
    private String p7;
    @ExcelProperty(index = 8)
    private String p8;
    @ExcelProperty(index = 9)
    private String p9;
    @ExcelProperty(index = 10)
    private String p10;
    @ExcelProperty(index = 11)
    private String p11;
    @ExcelProperty(index = 12)
    private String p12;
    @ExcelProperty(index = 13)
    private String p13;

}
package com.alibaba.easyexcel.test.temp;

import static org.apache.poi.ss.usermodel.BorderStyle.THIN;

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ContentFontStyle;
import com.alibaba.excel.annotation.write.style.ContentLoopMerge;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
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 lombok.Data;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;

/**
 * @author Jiaju Zhuang
 */
@Data
@HeadStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 11, horizontalAlignment = HorizontalAlignment.CENTER, wrapped = true)
// 头背景设置成红色 IndexedColors.RED.getIndex()
//@HeadStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 10)
// 头字体设置成20
// 内容的背景设置成绿色 IndexedColors.GREEN.getIndex()
//@ContentStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 11, horizontalAlignment = HorizontalAlignment.CENTER, wrapped = true)
@ContentRowHeight(30)
@ContentFontStyle(bold=true,fontHeightInPoints = 11)
@ContentStyle( borderRight = THIN,borderLeft =  THIN, borderTop = THIN, borderBottom = THIN, fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 1, horizontalAlignment = HorizontalAlignment.CENTER, wrapped = true)
public class QuestionHeader {

    //    @ContentLoopMerge(eachRow = 1, columnExtend = 1)
    @ExcelProperty(index = 0)
    private String no = "序号";
    @ContentLoopMerge(eachRow = 1, columnExtend = 4)
    @ExcelProperty(index = 1)
    private String path = "问题目录";
    @ContentLoopMerge(eachRow = 1, columnExtend = 9)
    @ExcelProperty(index = 5)
    private String content = "计划开始时间";
    @ExcelProperty(index = 14)
    private String flag = "标记";

    @ExcelProperty(index = 2)
    private String p2;
    @ExcelProperty(index = 3)
    private String p3;
    @ExcelProperty(index = 4)
    private String p4;
    @ExcelProperty(index = 6)
    private String p6;
    @ExcelProperty(index = 7)
    private String p7;
    @ExcelProperty(index = 8)
    private String p8;
    @ExcelProperty(index = 9)
    private String p9;
    @ExcelProperty(index = 10)
    private String p10;
    @ExcelProperty(index = 11)
    private String p11;
    @ExcelProperty(index = 12)
    private String p12;
    @ExcelProperty(index = 13)
    private String p13;
}

package com.alibaba.easyexcel.test.temp;

import static org.apache.poi.ss.usermodel.BorderStyle.THIN;

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ContentLoopMerge;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.ContentStyle;
import lombok.Data;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;

/**
 * @author Jiaju Zhuang
 */
@Data
@ContentRowHeight(30)
@ContentStyle( borderRight = THIN,borderLeft =  THIN,   borderTop = THIN, borderBottom = THIN, fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 1, horizontalAlignment = HorizontalAlignment.CENTER, wrapped = true)
public class TargetData {

    @ContentLoopMerge(eachRow = 1, columnExtend = 7)
    @ExcelProperty(index = 0)
    private String name1 = "厦门天下好发发发发发反反复复好工作有限公司";
    @ContentLoopMerge(eachRow = 1, columnExtend = 4)
    @ExcelProperty(index = 7)
    private String people1 = "张三丰 ";
    @ContentLoopMerge(eachRow = 1, columnExtend = 4)
    @ExcelProperty(index = 11)
    private String data1 = "2020/2/12";


    @ExcelProperty(index = 1)
    private String p1;
    @ExcelProperty(index = 2)
    private String p2;
    @ExcelProperty(index = 3)
    private String p3;
    @ExcelProperty(index = 4)
    private String p4;
    @ExcelProperty(index = 5)
    private String p5;
    @ExcelProperty(index = 6)
    private String p6;
    @ExcelProperty(index = 8)
    private String p8;
    @ExcelProperty(index = 9)
    private String p9;
    @ExcelProperty(index = 10)
    private String p10;
    @ExcelProperty(index = 12)
    private String p12;
    @ExcelProperty(index = 13)
    private String p13;
    @ExcelProperty(index = 14)
    private String p14;
}
package com.alibaba.easyexcel.test.temp;

import static org.apache.poi.ss.usermodel.BorderStyle.THIN;
import static org.apache.poi.ss.usermodel.IndexedColors.YELLOW;

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ContentFontStyle;
import com.alibaba.excel.annotation.write.style.ContentLoopMerge;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
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 lombok.Data;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;

/**
 * @author Jiaju Zhuang
 */
@Data
//@HeadStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 11, horizontalAlignment = HorizontalAlignment.CENTER, wrapped = true)
// 头背景设置成红色 IndexedColors.RED.getIndex()
//@HeadStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 10)
// 内容的背景设置成绿色 IndexedColors.GREEN.getIndex()
//@ContentStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 11, horizontalAlignment = HorizontalAlignment.CENTER, wrapped = true)
// 内容字体设置成20
@ContentFontStyle(bold=true,fontHeightInPoints = 11)
//@ContentStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 11, horizontalAlignment = HorizontalAlignment.CENTER, wrapped = true)
@ContentStyle( borderRight = THIN,borderLeft =  THIN,  borderTop = THIN, borderBottom = THIN, fillPatternType = FillPatternType.SOLID_FOREGROUND,
    fillForegroundColor = 1, horizontalAlignment = HorizontalAlignment.CENTER, wrapped = true )
@ContentRowHeight(25)
public class TargetHeader {

    @ContentLoopMerge(eachRow = 1, columnExtend = 7)
    @ExcelProperty(index = 0)
    private String name = "对象名称";
    @ContentLoopMerge(eachRow = 1, columnExtend = 4)
    @ExcelProperty(index = 7)
    private String people = "人员";
    @ContentLoopMerge(eachRow = 1, columnExtend = 4)
    @ExcelProperty(index = 11)
    private String data = "计划开始时间";


    @ExcelProperty(index = 1)
    private String p1;
    @ExcelProperty(index = 2)
    private String p2;
    @ExcelProperty(index = 3)
    private String p3;
    @ExcelProperty(index = 4)
    private String p4;
    @ExcelProperty(index = 5)
    private String p5;
    @ExcelProperty(index = 6)
    private String p6;
    @ExcelProperty(index = 8)
    private String p8;
    @ExcelProperty(index = 9)
    private String p9;
    @ExcelProperty(index = 10)
    private String p10;
    @ExcelProperty(index = 12)
    private String p12;
    @ExcelProperty(index = 13)
    private String p13;
    @ExcelProperty(index = 14)
    private String p14;
}

模板图片

easy-excel复杂格式_第1张图片

打印效果 

easy-excel复杂格式_第2张图片

第二部分:一个模板打印到多sheet页面

利用poi复制sheet的模板

public InputStream generateTemplate(int sheetNum, String sheetName) {
    log.info("sheetNum {}", sheetNum);
    InputStream inputStreamTemplate =
        this.getClass().getClassLoader().getResourceAsStream("static/questionExport.xlsx");
    XSSFWorkbook workbook = null;
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    try {
      workbook = new XSSFWorkbook(inputStreamTemplate);
      workbook.setSheetName(0, sheetName + "1");
      for (int i = 1; i < sheetNum ; i++) {
        //复制模板,得到第i个sheet
        int num = i + 1;
        workbook.cloneSheet(0, sheetName + num);
      }
      workbook.write(bos);
      byte[] bArray = bos.toByteArray();
      InputStream is = new ByteArrayInputStream(bArray);
      return is;
    } catch (Exception e ) {
      log.error(e.getMessage(), e);
      throw new ServiceException("模板生成错误", "模板生成错误");
    }
  }

    

   InputStream inputStreamTemplate =  generateTemplate(projectIdList.size(), sheetNameFmt);
    ExcelWriter excelWriter = EasyExcel.write(outputStream)     
        .withTemplate(inputStreamTemplate).build();
      WriteSheet writeSheet = EasyExcel.writerSheet().sheetName(sheetName).build();
      excelWriter.fill(exportProjectVo, writeSheet);
      excelWriter.finish();

3. 高度自适应

1.重新修改 easy-excel的AbstractRowHeightStyleStrategy的方法的

protected abstract void setContentColumnHeight(Row row, int relativeRowIndex);

protected abstract void setContentColumnHeight(Row row, Integer relativeRowIndex);

调试时候,发现使用模板的时候不改这个方法在有使用模板的时候回报类型转换错误;

2.自适应代码

    ExcelWriter excelWriter = EasyExcel.write(outputStream)
        .registerWriteHandler(new CustomCellWriteHeightConfig())
        .withTemplate(inputStreamTemplate).build();
package com.xmsme.ddi.excel;

import com.alibaba.excel.write.style.row.AbstractRowHeightStyleStrategy;
import java.util.Iterator;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;

/***
 * excel高度自适应
 */
@Slf4j
public class CustomCellWriteHeightConfig extends AbstractRowHeightStyleStrategy {
  /** 默认高度 */
  private static final Integer DEFAULT_HEIGHT = 300;

  public static int GetMergeNum(Cell cell, Sheet sheet) {
    int mergeSize = 1;
    List mergedRegions = sheet.getMergedRegions();
    for (CellRangeAddress cellRangeAddress : mergedRegions) {
      if (cellRangeAddress.isInRange(cell)) {
        // 获取合并的行数
        mergeSize = cellRangeAddress.getLastColumn() - cellRangeAddress.getFirstColumn() + 1;
        // 获取合并的列数
        // mergeSize =	cellRangeAddress.getFirstRow()-cellRangeAddress.getLastRow()+1;
        break;
      }
    }
    return mergeSize;
  }

  @Override
  protected void setHeadColumnHeight(Row row, Integer relativeRowIndex) {}

  @Override
  protected void setContentColumnHeight(Row row1, Integer relativeRowIndex) {

    if (relativeRowIndex != null) {
      handleRow(row1, row1);
      return;
    }
    Iterator rowIterator = row1.getSheet().rowIterator();

    while (rowIterator.hasNext()) {
      Row row = rowIterator.next();
      handleRow(row1, row);
    }
  }

  private void handleRow(Row row1, Row row) {
    Iterator cellIterator = row.cellIterator();

    if (!cellIterator.hasNext()) {
      return;
    }
    // 默认为 1行高度
    Integer maxHeight = 1;
    while (cellIterator.hasNext()) {
      Cell cell = cellIterator.next();
      switch (cell.getCellTypeEnum()) {
        case STRING:
          int width = row1.getSheet().getColumnWidth(cell.getColumnIndex());

          int widthSize = Double.valueOf(GetMergeNum(cell, row.getSheet()) * 2.5).intValue();
          //            log.info(
          //                "{} {} {} {} {} {}",
          //                cell.getAddress(),
          //                cell.getRowIndex(),
          //                cell.getColumnIndex(),
          //                cell.getStringCellValue(),
          //                GetMergeNum(cell, row.getSheet()),
          //                row1.getSheet().getColumnWidth(cell.getColumnIndex()));
//          log.info(
//              "{} widthSize=>{} length => {}",
//              cell.getStringCellValue(),
//              widthSize,
//              cell.getStringCellValue().length() / widthSize);
          if (cell.getStringCellValue().length() > widthSize && widthSize != 0) {
            int modValue = cell.getStringCellValue().length() % widthSize;
            int length =
                modValue == 0
                    ? cell.getStringCellValue().length() / widthSize
                    : cell.getStringCellValue().length() / widthSize + 1;
            maxHeight = Math.max(maxHeight, length);
          }
          break;
        default:
          break;
      }
    }
    short targetHeight = (short) (maxHeight * DEFAULT_HEIGHT);
    short height = row.getHeight();
//    log.info("targetHeight {} => {}", targetHeight, height);
    if (targetHeight > height) {
      row.setHeight(targetHeight);
    }
  }
}

你可能感兴趣的:(java,jar)