package com.alibaba.excel.context; import static com.alibaba.excel.util.StyleUtil.buildSheetStyle; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.CellRangeAddress; import com.alibaba.excel.converters.ConverterRegistryCenter; import com.alibaba.excel.event.WriteHandler; import com.alibaba.excel.metadata.BaseRowModel; import com.alibaba.excel.metadata.ExcelHeadProperty; import com.alibaba.excel.metadata.Table; import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.excel.util.CollectionUtils; import com.alibaba.excel.util.StyleUtil; import com.alibaba.excel.util.WorkBookUtil; /** * A context is the main anchorage point of a excel writer. * * @author jipengfei */ public class WriteContextImpl implements WriteContext { /*** * The sheet currently written */ private Sheet currentSheet; /** * current param */ private com.alibaba.excel.metadata.Sheet currentSheetParam; /** * The sheet currently written's name */ private String currentSheetName; /** * */ private Table currentTable; /** * Excel type */ private ExcelTypeEnum excelType; /** * POI Workbook */ private Workbook workbook; /** * Final output stream */ private OutputStream outputStream; /** * Written form collection */ private Map tableMap = new ConcurrentHashMap(); /** * Cell default style */ private CellStyle defaultCellStyle; /** * Current table head style */ private CellStyle currentHeadCellStyle; /** * Current table content style */ private CellStyle currentContentCellStyle; /** * the header attribute of excel */ private ExcelHeadProperty excelHeadProperty; private boolean needHead = true; private WriteHandler writeHandler; private ConverterRegistryCenter registryCenter; public WriteHandler getWriteHandler() { return writeHandler; } public WriteContextImpl(InputStream templateInputStream, OutputStream out, ExcelTypeEnum excelType, boolean needHead, WriteHandler writeHandler, ConverterRegistryCenter registryCenter) throws IOException { this.needHead = needHead; this.outputStream = out; this.writeHandler = writeHandler; this.workbook = WorkBookUtil.createWorkBook(templateInputStream, excelType); this.defaultCellStyle = StyleUtil.buildDefaultCellStyle(this.workbook); this.registryCenter = registryCenter; } /** * @param sheet */ @Override public void currentSheet(com.alibaba.excel.metadata.Sheet sheet) { if (null == currentSheetParam || currentSheetParam.getSheetNo() != sheet.getSheetNo()) { cleanCurrentSheet(); currentSheetParam = sheet; try { this.currentSheet = workbook.getSheetAt(sheet.getSheetNo() - 1); } catch (Exception e) { this.currentSheet = WorkBookUtil.createSheet(workbook, sheet); if (null != writeHandler) { this.writeHandler.sheet(sheet.getSheetNo(), currentSheet); } } buildSheetStyle(currentSheet, sheet.getColumnWidthMap()); /** **/ this.initCurrentSheet(sheet); } } private void initCurrentSheet(com.alibaba.excel.metadata.Sheet sheet) { /** **/ initExcelHeadProperty(sheet.getHead(), sheet.getClazz()); initTableStyle(sheet.getTableStyle()); initTableHead(); } private void cleanCurrentSheet() { this.currentSheet = null; this.currentSheetParam = null; this.excelHeadProperty = null; this.currentHeadCellStyle = null; this.currentContentCellStyle = null; this.currentTable = null; } /** * init excel header * * @param head * @param clazz */ private void initExcelHeadProperty(List> head, Class clazz) { if (head != null || clazz != null) { this.excelHeadProperty = new ExcelHeadProperty(clazz, head); } } public void initTableHead() { if (needHead && null != excelHeadProperty && !CollectionUtils.isEmpty(excelHeadProperty.getHead())) { int startRow = currentSheet.getLastRowNum(); if (startRow > 0) { startRow += 4; } else { startRow = currentSheetParam.getStartRow(); } addMergedRegionToCurrentSheet(startRow); int i = startRow; for (; i < this.excelHeadProperty.getRowNum() + startRow; i++) { Row row = WorkBookUtil.createRow(currentSheet, i); if (null != writeHandler) { this.writeHandler.row(i, row); } addOneRowOfHeadDataToExcel(row, this.excelHeadProperty.getHeadByRowNum(i - startRow)); } } } private void addMergedRegionToCurrentSheet(int startRow) { for (com.alibaba.excel.metadata.CellRange cellRangeModel : excelHeadProperty.getCellRangeModels()) { currentSheet.addMergedRegion(new CellRangeAddress(cellRangeModel.getFirstRow() + startRow, cellRangeModel.getLastRow() + startRow, cellRangeModel.getFirstCol(), cellRangeModel.getLastCol())); } } private void addOneRowOfHeadDataToExcel(Row row, List headByRowNum) { if (headByRowNum != null && headByRowNum.size() > 0) { for (int i = 0; i < headByRowNum.size(); i++) { Cell cell = WorkBookUtil.createCell(row, i, getCurrentHeadCellStyle(), headByRowNum.get(i)); if (null != writeHandler) { this.writeHandler.cell(i, cell); } } } } private void initTableStyle(com.alibaba.excel.metadata.TableStyle tableStyle) { if (tableStyle != null) { this.currentHeadCellStyle = StyleUtil.buildCellStyle(this.workbook, tableStyle.getTableHeadFont(), tableStyle.getTableHeadBackGroundColor()); this.currentContentCellStyle = StyleUtil.buildCellStyle(this.workbook, tableStyle.getTableContentFont(), tableStyle.getTableContentBackGroundColor()); } } private void cleanCurrentTable() { this.excelHeadProperty = null; this.currentHeadCellStyle = null; this.currentContentCellStyle = null; this.currentTable = null; } @Override public void currentTable(Table table) { if (null == currentTable || currentTable.getTableNo() != table.getTableNo()) { cleanCurrentTable(); this.currentTable = table; this.initExcelHeadProperty(table.getHead(), table.getClazz()); this.initTableStyle(table.getTableStyle()); this.initTableHead(); } } public ExcelHeadProperty getExcelHeadProperty() { return this.excelHeadProperty; } public boolean needHead() { return this.needHead; } @Override public Sheet getCurrentSheet() { return currentSheet; } public void setCurrentSheet(Sheet currentSheet) { this.currentSheet = currentSheet; } public String getCurrentSheetName() { return currentSheetName; } public void setCurrentSheetName(String currentSheetName) { this.currentSheetName = currentSheetName; } public ExcelTypeEnum getExcelType() { return excelType; } public void setExcelType(ExcelTypeEnum excelType) { this.excelType = excelType; } @Override public OutputStream getOutputStream() { return outputStream; } public CellStyle getCurrentHeadCellStyle() { return this.currentHeadCellStyle == null ? defaultCellStyle : this.currentHeadCellStyle; } public CellStyle getCurrentContentStyle() { return this.currentContentCellStyle; } @Override public Workbook getWorkbook() { return workbook; } public com.alibaba.excel.metadata.Sheet getCurrentSheetParam() { return currentSheetParam; } public void setCurrentSheetParam(com.alibaba.excel.metadata.Sheet currentSheetParam) { this.currentSheetParam = currentSheetParam; } public Table getCurrentTable() { return currentTable; } public void setCurrentTable(Table currentTable) { this.currentTable = currentTable; } @Override public ConverterRegistryCenter getConverterRegistryCenter() { return registryCenter; } }