> Java > java지도 시간 > 본문

EasyExcel을 사용하여 Java에서 셀을 병합하는 방법

王林
풀어 주다: 2023-04-27 08:55:15
앞으로
5503명이 탐색했습니다.

1. 프로젝트 시나리오:

소개: 환급 양식을 내보내면 지정된 Excel 템플릿에 따라 해당 양식이 자동으로 대체된 다음 새 Excel이 다시 생성되어야 합니다. 주어진 Excel 템플릿에서 일부 필드는 아래와 같이 셀 병합되었습니다.

EasyExcel을 사용하여 Java에서 셀을 병합하는 방법

2. 문제 설명

환급 양식에는 여러 환급 내용이 포함될 수 있으므로 템플릿에 미리 설정된 내용을 초과하면 자동으로 줄 바꿈되지만 다음에 따라 셀이 자동으로 병합되지는 않습니다. 아래와 같이 템플릿의 스타일을 변경합니다.

EasyExcel을 사용하여 Java에서 셀을 병합하는 방법

3. 이유 분석:

우선, 엑셀에서 데이터를 삽입하고 행을 자동으로 줄 바꿈할 때, 행 줄 바꿈된 데이터가 이전 행의 스타일에 따라 자동으로 병합되지 않는 것을 직관적으로 알 수 있습니다. .
그래서 코드를 사용하여 이러한 열을 수동으로 병합한 다음 테두리 스타일을 추가하여 문제를 해결하는 방법을 생각했습니다.

4. 해결 방법:

  1. 위 아이디어에 따라 셀을 직접 병합한 다음 테두리를 추가해도 문제가 직접 해결되지는 않습니다.

  2. 뒷쪽에 빈 셀을 하나씩 생성한 후 병합해야 문제를 해결할 수 있습니다. 셀을 생성하는 코드는 아래 CustomCellWriteHandler 클래스에 설명되어 있습니다. CustomCellWriteHandler类中说明。

这也算是耗费一整天时间踩的坑。。。

public static void outExcelBalance(String modelFile, String newFile, Map<String, Object> map, List<FillDataExpense> fillData, HttpServletResponse response, String fileName){
        //定义model模板中默认的行数
        int firstRow = 7; //excel中表示第八行,即模板中默认的一条
        int lastRow = 7;
        InputStream is = null;
        File file = new File(modelFile);
        File file1 = new File(newFile);
        //String file1Name = file1.getName();
        BufferedInputStream bis = null;
        try {
            if (!file.exists()) {
                copyFileUsingJava7Files(file, file1);
            }

            //TODO 单元格样式
            Set<Integer> rowsBorderSet= new HashSet<>();
            CustomCellWriteHandler customCellWriteHandler = null;

            //TODO 单元格合并
            List<CellRangeAddress> cellRangeAddresss = new ArrayList<>();

            if (ListUtils.isNotNull(fillData)){
                if (fillData.size() > 1){
                    //合并每条报销单的第3-10列
                    for (int i = 1; i < fillData.size(); i++) {
                        firstRow++;
                        lastRow++;

                        cellRangeAddresss.add(new CellRangeAddress(firstRow, lastRow, 2, 9));
                        cellRangeAddresss.add(new CellRangeAddress(firstRow, lastRow, 10, 11));

                        rowsBorderSet.add(firstRow);
                    }
                }
            }
            customCellWriteHandler = new CustomCellWriteHandler(rowsBorderSet);
            MyMergeStrategy myMergeStrategy = new MyMergeStrategy(cellRangeAddresss);

            ExcelWriter excelWriter = EasyExcel.write(newFile)
                    //注册单元格式
                    .registerWriteHandler(customCellWriteHandler)
                    //注册合并策略
                    .registerWriteHandler(myMergeStrategy)
                    .withTemplate(modelFile).build();
            WriteSheet writeSheet = EasyExcel.writerSheet().build();
            FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
            if (!ListUtil.listIsEmpty(fillData)){
                excelWriter.fill(fillData, fillConfig, writeSheet);
                //excelWriter.fill(fillData, fillConfig, writeSheet);
            }
            excelWriter.fill(map, writeSheet);
            excelWriter.finish();
            response.setHeader("content-type", "text/plain");
            response.setHeader("content-type", "application/x-msdownload;");
            response.setContentType("text/plain; charset=utf-8");
            response.setHeader("Content-Disposition", "attachment; filename=" + new String(fileName.getBytes("utf-8"),"ISO8859-1"));
            byte[] buff = new byte[1024];

            OutputStream os = null;
            os = response.getOutputStream();
            bis = new BufferedInputStream(new FileInputStream(file1));
            int i = bis.read(buff);

            while (i != -1) {
                os.write(buff, 0, buff.length);
                os.flush();
                i = bis.read(buff);
            }
        }
        catch (Exception e){
            LOGGER.error(e.getMessage());
        }
        finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            // 删除生成文件
                /*if (file1.exists()) {
                    file1.delete();
                }*/
        }
    }
로그인 후 복사

单元格合并MyMergeStrategy类代码:

public class MyMergeStrategy extends AbstractMergeStrategy {

    //合并坐标集合
    private List<CellRangeAddress> cellRangeAddresss;

    //构造
    public MyMergeStrategy(List<CellRangeAddress> cellRangeAddresss) {
        this.cellRangeAddresss = cellRangeAddresss;
    }

    @Override
    protected void merge(Sheet sheet, Cell cell, Head head, Integer integer) {
        if (ListUtils.isNotNull(cellRangeAddresss)) {
            if (cell.getRowIndex() == 7 ) {
                for (CellRangeAddress item : cellRangeAddresss) {
                    sheet.addMergedRegionUnsafe(item);
                }
            }
        }
    }
}
로그인 후 복사

单元格样式CustomCellWriteHandler

이 구덩이는 밟는데 꼬박 하루가 걸렸다고 할 수 있습니다. . .

public class CustomCellWriteHandler implements CellWriteHandler {
    private static final Logger LOGGER = LoggerFactory.getLogger(CustomCellWriteHandler.class);

    //标黄行宽集合
    private Set<Integer> rowIndexs;

    //构造
    public CustomCellWriteHandler(Set<Integer> rowIndexs) {
        this.rowIndexs = rowIndexs;
    }

    public CustomCellWriteHandler() {
    }

    @Override
    public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {
        LOGGER.info("beforeCellCreate~~~~");
    }

    @Override
    public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
        LOGGER.info("afterCellCreate~~~~");
    }

    @Override
    public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer integer, Boolean aBoolean) {

    }

    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {

          //获取工作簿
//        HSSFWorkbook wb = new HSSFWorkbook();
//        //获取sheet
//        HSSFSheet sheet = wb.createSheet();
//        HSSFRow row = sheet.createRow();
//        HSSFCellStyle style = wb.createCellStyle();

        // 这里可以对cell进行任何操作
        if (CollectionUtils.isNotEmpty(rowIndexs)) {
            Workbook workbook = writeSheetHolder.getSheet().getWorkbook();
            CellStyle cellStyle = workbook.createCellStyle();

            Sheet sheet = writeSheetHolder.getSheet();
            cellStyle.setAlignment(new HSSFWorkbook().createCellStyle().getAlignment());
            cellStyle.setBorderBottom(BorderStyle.THIN); //下边框
            cellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
            cellStyle.setBorderLeft(BorderStyle.THIN);//左边框
            cellStyle.setBorderTop(BorderStyle.THIN);//上边框
            cellStyle.setBorderRight(BorderStyle.THIN);//右边框
            cellStyle.setWrapText(true);//自动换行

            //字体
//            Font cellFont = workbook.createFont();
//            cellFont.setBold(true);
//            cellStyle.setFont(cellFont);
//            //标黄,要一起设置
//            cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); //设置前景填充样式
//            cellStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());//前景填充色

            if (rowIndexs.contains(cell.getRowIndex())) {
                Row row = null;
                //循环创建空白单元格
                for (int i = 0; i < rowIndexs.size(); i++) {
                    for (Integer rowIndex : rowIndexs){
                        //创建4-10列的空白格
                        row = sheet.getRow(rowIndex.intValue());
                        if (row == null){
                            row = sheet.createRow(rowIndex.intValue());
                        }
                        for (int j = 3; j <= 9; j++) {
                            //获取8行的cell列
                            cell = row.createCell(j);
                            cell.setCellStyle(cellStyle);
                            cell.setCellValue(" ");
                            LOGGER.info("第{}行,第{}列创建空白格。", cell.getRowIndex(), j);
                        }
                        //创建12列的红白格
                        cell = row.createCell(11);
                        cell.setCellStyle(cellStyle);
                        cell.setCellValue(" ");
                        LOGGER.info("第{}行,第11列创建空白格。", cell.getRowIndex());
                        //创建21列的空白格
                        cell = row.createCell(21);
                        cell.setCellStyle(cellStyle);
                        cell.setCellValue(" ");
                        LOGGER.info("第{}行,第21列创建空白格。", cell.getRowIndex());
                    }
                }
            }
        }
    }
}
로그인 후 복사

셀 병합 MyMergeStrategy 클래스 코드:

1. 
	//创建单元格样式
	CustomCellWriteHandler customCellWriteHandler = new CustomCellWriteHandler(参数按需给定);
2. 
	//单元格进行合并
	List<CellRangeAddress> cellRangeAddresss = new ArrayList<>();
	//例如:从firstRow行到lastRow行的2列到9列合并
    cellRangeAddresss.add(new CellRangeAddress(firstRow, lastRow, 2, 9));
    cellRangeAddresss.add(new CellRangeAddress(firstRow, lastRow, 10, 11));
    MyMergeStrategy myMergeStrategy = new MyMergeStrategy(cellRangeAddresss);
3. 
	//注册以上两种策略
	ExcelWriter excelWriter = EasyExcel.write(newFile)
    //注册单元格式
    .registerWriteHandler(customCellWriteHandler)
    //注册合并策略
    .registerWriteHandler(myMergeStrategy)
    .withTemplate(modelFile).build();
로그인 후 복사

셀 스타일 CustomCellWriteHandler 클래스 코드:

rrreee

5. 요약

🎜핵심 단계: 🎜rrreee🎜지침: 내가 처음 수리를 시작했지만 병합하기 전에 앞으로 모든 빈 셀을 생성해야 한다고 생각하지 않았습니다. 항상 툴 문제인 줄 알았는데, 계속해서 솔루션을 읽어보니 빈 셀을 먼저 만든 다음 병합해야 한다고 하더군요. 드디어 완벽하게 해결되었습니다. 🎜🎜 코드 부분은 비즈니스 코드이다 보니 불필요한 것들이 많이 섞여있습니다. 🎜

위 내용은 EasyExcel을 사용하여 Java에서 셀을 병합하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:yisu.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!