WriteContextImpl.java 14.3 KB
Newer Older
clevertension's avatar
clevertension 已提交
1 2 3 4
package com.alibaba.excel.context;

import java.io.IOException;
import java.util.List;
Z
zhuangjiaju 已提交
5
import java.util.Map;
clevertension's avatar
clevertension 已提交
6 7 8 9 10

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;
Z
zhuangjiaju 已提交
11 12
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
clevertension's avatar
clevertension 已提交
13

Z
zhuangjiaju 已提交
14
import com.alibaba.excel.exception.ExcelGenerateException;
Z
zhuangjiaju 已提交
15
import com.alibaba.excel.metadata.Head;
clevertension's avatar
clevertension 已提交
16
import com.alibaba.excel.metadata.Table;
Z
zhuangjiaju 已提交
17 18 19 20
import com.alibaba.excel.metadata.holder.ConfigurationSelector;
import com.alibaba.excel.metadata.holder.SheetHolder;
import com.alibaba.excel.metadata.holder.TableHolder;
import com.alibaba.excel.metadata.holder.WorkbookHolder;
Z
zhuangjiaju 已提交
21
import com.alibaba.excel.metadata.property.ExcelHeadProperty;
clevertension's avatar
clevertension 已提交
22
import com.alibaba.excel.util.WorkBookUtil;
23 24
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.handler.RowWriteHandler;
Z
zhuangjiaju 已提交
25 26
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.handler.WorkbookWriteHandler;
Z
zhuangjiaju 已提交
27
import com.alibaba.excel.write.handler.WriteHandler;
clevertension's avatar
clevertension 已提交
28 29 30 31 32 33 34

/**
 * A context is the main anchorage point of a excel writer.
 *
 * @author jipengfei
 */
public class WriteContextImpl implements WriteContext {
Z
zhuangjiaju 已提交
35 36 37

    private static final Logger LOGGER = LoggerFactory.getLogger(WriteContextImpl.class);

clevertension's avatar
clevertension 已提交
38
    /**
Z
zhuangjiaju 已提交
39
     * The Workbook currently written
clevertension's avatar
clevertension 已提交
40
     */
Z
zhuangjiaju 已提交
41
    private WorkbookHolder currentWorkbookHolder;
clevertension's avatar
clevertension 已提交
42
    /**
Z
zhuangjiaju 已提交
43
     * Current sheet holder
clevertension's avatar
clevertension 已提交
44
     */
Z
zhuangjiaju 已提交
45
    private SheetHolder currentSheetHolder;
clevertension's avatar
clevertension 已提交
46
    /**
Z
zhuangjiaju 已提交
47
     * The table currently written
clevertension's avatar
clevertension 已提交
48
     */
Z
zhuangjiaju 已提交
49
    private TableHolder currentTableHolder;
clevertension's avatar
clevertension 已提交
50
    /**
Z
zhuangjiaju 已提交
51
     * Configuration of currently operated cell
clevertension's avatar
clevertension 已提交
52
     */
Z
zhuangjiaju 已提交
53 54
    private ConfigurationSelector currentConfigurationSelector;

Z
zhuangjiaju 已提交
55 56 57 58
    public WriteContextImpl(com.alibaba.excel.metadata.Workbook workbook) {
        if (workbook == null) {
            throw new IllegalArgumentException("Workbook argument cannot be null");
        }
Z
zhuangjiaju 已提交
59 60 61
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Begin to Initialization 'WriteContextImpl'");
        }
Z
zhuangjiaju 已提交
62
        initCurrentWorkbookHolder(workbook);
Z
zhuangjiaju 已提交
63
        beforeWorkbookCreate();
Z
zhuangjiaju 已提交
64
        try {
Z
zhuangjiaju 已提交
65
            currentWorkbookHolder.setWorkbook(WorkBookUtil.createWorkBook(workbook));
Z
zhuangjiaju 已提交
66 67 68
        } catch (IOException e) {
            throw new ExcelGenerateException("Create workbook failure", e);
        }
Z
zhuangjiaju 已提交
69
        afterWorkbookCreate();
Z
zhuangjiaju 已提交
70 71 72 73 74
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Initialization 'WriteContextImpl' complete");
        }
    }

Z
zhuangjiaju 已提交
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
    private void beforeWorkbookCreate() {
        List<WriteHandler> handlerList = currentConfigurationSelector.writeHandlerMap().get(WorkbookWriteHandler.class);
        if (handlerList == null || handlerList.isEmpty()) {
            return;
        }
        for (WriteHandler writeHandler : handlerList) {
            if (writeHandler instanceof WorkbookWriteHandler) {
                ((WorkbookWriteHandler)writeHandler).beforeWorkbookCreate();
            }
        }
    }

    private void afterWorkbookCreate() {
        List<WriteHandler> handlerList = currentConfigurationSelector.writeHandlerMap().get(WorkbookWriteHandler.class);
        if (handlerList == null || handlerList.isEmpty()) {
            return;
        }
        for (WriteHandler writeHandler : handlerList) {
            if (writeHandler instanceof WorkbookWriteHandler) {
                ((WorkbookWriteHandler)writeHandler).afterWorkbookCreate(currentWorkbookHolder);
            }
        }
    }

Z
zhuangjiaju 已提交
99
    private void initCurrentWorkbookHolder(com.alibaba.excel.metadata.Workbook workbook) {
100
        currentWorkbookHolder = new WorkbookHolder(workbook);
Z
zhuangjiaju 已提交
101 102 103 104 105
        currentConfigurationSelector = currentWorkbookHolder;
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("CurrentConfigurationSelector is currentWorkbookHolder");
        }
    }
clevertension's avatar
clevertension 已提交
106 107 108 109 110 111

    /**
     * @param sheet
     */
    @Override
    public void currentSheet(com.alibaba.excel.metadata.Sheet sheet) {
Z
zhuangjiaju 已提交
112 113 114
        if (sheet == null) {
            throw new IllegalArgumentException("Sheet argument cannot be null");
        }
Z
zhuangjiaju 已提交
115 116
        if (sheet.getSheetNo() == null || sheet.getSheetNo() <= 0) {
            sheet.setSheetNo(0);
Z
zhuangjiaju 已提交
117
        }
Z
zhuangjiaju 已提交
118 119 120
        if (currentWorkbookHolder.getHasBeenInitializedSheet().containsKey(sheet.getSheetNo())) {
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("Sheet:{} is already existed", sheet.getSheetNo());
clevertension's avatar
clevertension 已提交
121
            }
Z
zhuangjiaju 已提交
122
            currentSheetHolder = currentWorkbookHolder.getHasBeenInitializedSheet().get(sheet.getSheetNo());
123
            currentSheetHolder.setNewInitialization(Boolean.FALSE);
Z
zhuangjiaju 已提交
124
            currentTableHolder = null;
Z
zhuangjiaju 已提交
125 126 127 128 129
            currentConfigurationSelector = currentSheetHolder;
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("CurrentConfigurationSelector is currentSheetHolder");
            }
            return;
clevertension's avatar
clevertension 已提交
130
        }
Z
zhuangjiaju 已提交
131
        initCurrentSheetHolder(sheet);
Z
zhuangjiaju 已提交
132
        beforeSheetCreate();
Z
zhuangjiaju 已提交
133
        // Initialization current sheet
Z
zhuangjiaju 已提交
134
        initSheet(sheet);
Z
zhuangjiaju 已提交
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
        afterSheetCreate();
    }

    private void beforeSheetCreate() {
        List<WriteHandler> handlerList = currentConfigurationSelector.writeHandlerMap().get(SheetWriteHandler.class);
        if (handlerList == null || handlerList.isEmpty()) {
            return;
        }
        for (WriteHandler writeHandler : handlerList) {
            if (writeHandler instanceof SheetWriteHandler) {
                ((SheetWriteHandler)writeHandler).beforeSheetCreate(currentWorkbookHolder, currentSheetHolder);
            }
        }
    }

    private void afterSheetCreate() {
        List<WriteHandler> handlerList = currentConfigurationSelector.writeHandlerMap().get(SheetWriteHandler.class);
        if (handlerList == null || handlerList.isEmpty()) {
            return;
        }
        for (WriteHandler writeHandler : handlerList) {
            if (writeHandler instanceof SheetWriteHandler) {
                ((SheetWriteHandler)writeHandler).afterSheetCreate(currentWorkbookHolder, currentSheetHolder);
            }
        }
160 161 162 163
        if (null != currentWorkbookHolder.getWriteHandler()) {
            currentWorkbookHolder.getWriteHandler().sheet(currentSheetHolder.getSheetNo(),
                currentSheetHolder.getSheet());
        }
Z
zhuangjiaju 已提交
164
    }
clevertension's avatar
clevertension 已提交
165

Z
zhuangjiaju 已提交
166
    private void initCurrentSheetHolder(com.alibaba.excel.metadata.Sheet sheet) {
167
        currentSheetHolder = new SheetHolder(sheet, currentWorkbookHolder);
Z
zhuangjiaju 已提交
168
        currentWorkbookHolder.getHasBeenInitializedSheet().put(sheet.getSheetNo(), currentSheetHolder);
Z
zhuangjiaju 已提交
169
        currentTableHolder = null;
Z
zhuangjiaju 已提交
170 171 172 173
        currentConfigurationSelector = currentSheetHolder;
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("CurrentConfigurationSelector is currentSheetHolder");
        }
clevertension's avatar
clevertension 已提交
174 175
    }

Z
zhuangjiaju 已提交
176
    private void initSheet(com.alibaba.excel.metadata.Sheet sheet) {
Z
zhuangjiaju 已提交
177 178 179 180 181 182 183 184
        Sheet currentSheet;
        try {
            currentSheet = currentWorkbookHolder.getWorkbook().getSheetAt(sheet.getSheetNo());
        } catch (Exception e) {
            if (LOGGER.isDebugEnabled()) {
                LOGGER.info("Can not find sheet:{} ,now create it", sheet.getSheetNo());
            }
            currentSheet = WorkBookUtil.createSheet(currentWorkbookHolder.getWorkbook(), sheet);
Z
zhuangjiaju 已提交
185
        }
Z
zhuangjiaju 已提交
186 187
        currentSheetHolder.setSheet(currentSheet);
        // Initialization head
Z
zhuangjiaju 已提交
188
        initHead(currentSheetHolder.getExcelHeadProperty());
clevertension's avatar
clevertension 已提交
189 190
    }

Z
zhuangjiaju 已提交
191
    public void initHead(ExcelHeadProperty excelHeadProperty) {
Z
zhuangjiaju 已提交
192
        if (!currentConfigurationSelector.needHead() || !currentSheetHolder.getExcelHeadProperty().hasHead()) {
Z
zhuangjiaju 已提交
193 194
            return;
        }
195 196
        int lastRowNum = currentSheetHolder.getSheet().getLastRowNum();
        int rowIndex = lastRowNum + currentConfigurationSelector.writeRelativeHeadRowIndex();
Z
zhuangjiaju 已提交
197
        // Combined head
198 199 200 201
        addMergedRegionToCurrentSheet(excelHeadProperty, rowIndex);
        for (int relativeRowIndex = 0, i = rowIndex; i < excelHeadProperty.getHeadRowNumber() + rowIndex;
            i++, relativeRowIndex++) {
            beforeRowCreate(rowIndex, relativeRowIndex);
Z
zhuangjiaju 已提交
202
            Row row = WorkBookUtil.createRow(currentSheetHolder.getSheet(), i);
203
            afterRowCreate(row, relativeRowIndex);
Z
zhuangjiaju 已提交
204
            addOneRowOfHeadDataToExcel(row, excelHeadProperty.getHeadMap(), relativeRowIndex);
205 206 207 208 209 210 211 212 213 214 215 216 217
        }
    }

    private void beforeRowCreate(int rowIndex, int relativeRowIndex) {
        List<WriteHandler> handlerList = currentConfigurationSelector.writeHandlerMap().get(RowWriteHandler.class);
        if (handlerList == null || handlerList.isEmpty()) {
            return;
        }
        for (WriteHandler writeHandler : handlerList) {
            if (writeHandler instanceof RowWriteHandler) {
                ((RowWriteHandler)writeHandler).beforeRowCreate(currentSheetHolder, currentTableHolder, rowIndex,
                    relativeRowIndex, true);
            }
clevertension's avatar
clevertension 已提交
218 219 220
        }
    }

221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
    private void afterRowCreate(Row row, int relativeRowIndex) {
        List<WriteHandler> handlerList = currentConfigurationSelector.writeHandlerMap().get(RowWriteHandler.class);
        if (handlerList == null || handlerList.isEmpty()) {
            return;
        }
        for (WriteHandler writeHandler : handlerList) {
            if (writeHandler instanceof RowWriteHandler) {
                ((RowWriteHandler)writeHandler).afterRowCreate(currentSheetHolder, currentTableHolder, row,
                    relativeRowIndex, true);
            }
        }
        if (null != currentWorkbookHolder.getWriteHandler()) {
            currentWorkbookHolder.getWriteHandler().row(row.getRowNum(), row);
        }
    }

    private void addMergedRegionToCurrentSheet(ExcelHeadProperty excelHeadProperty, int rowIndex) {
Z
zhuangjiaju 已提交
238
        for (com.alibaba.excel.metadata.CellRange cellRangeModel : excelHeadProperty.headCellRangeList()) {
239 240
            currentSheetHolder.getSheet().addMergedRegion(new CellRangeAddress(cellRangeModel.getFirstRow() + rowIndex,
                cellRangeModel.getLastRow() + rowIndex, cellRangeModel.getFirstCol(), cellRangeModel.getLastCol()));
clevertension's avatar
clevertension 已提交
241 242 243
        }
    }

Z
zhuangjiaju 已提交
244 245 246 247 248 249
    private void addOneRowOfHeadDataToExcel(Row row, Map<Integer, Head> headMap, int relativeRowIndex) {
        for (Map.Entry<Integer, Head> entry : headMap.entrySet()) {
            Head head = entry.getValue();
            beforeCellCreate(row, head, relativeRowIndex);
            Cell cell = WorkBookUtil.createCell(row, entry.getKey(), head.getHeadNameList().get(relativeRowIndex));
            afterCellCreate(head, cell, relativeRowIndex);
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278
        }
    }

    private void beforeCellCreate(Row row, Head head, int relativeRowIndex) {
        List<WriteHandler> handlerList = currentConfigurationSelector.writeHandlerMap().get(CellWriteHandler.class);
        if (handlerList == null || handlerList.isEmpty()) {
            return;
        }
        for (WriteHandler writeHandler : handlerList) {
            if (writeHandler instanceof CellWriteHandler) {
                ((CellWriteHandler)writeHandler).beforeCellCreate(currentSheetHolder, currentTableHolder, row, head,
                    relativeRowIndex, true);
            }
        }
    }

    private void afterCellCreate(Head head, Cell cell, int relativeRowIndex) {
        List<WriteHandler> handlerList = currentConfigurationSelector.writeHandlerMap().get(CellWriteHandler.class);
        if (handlerList == null || handlerList.isEmpty()) {
            return;
        }
        for (WriteHandler writeHandler : handlerList) {
            if (writeHandler instanceof CellWriteHandler) {
                ((CellWriteHandler)writeHandler).afterCellCreate(currentSheetHolder, currentTableHolder, cell, head,
                    relativeRowIndex, true);
            }
        }
        if (null != currentWorkbookHolder.getWriteHandler()) {
            currentWorkbookHolder.getWriteHandler().cell(cell.getRowIndex(), cell);
clevertension's avatar
clevertension 已提交
279 280 281 282 283
        }
    }

    @Override
    public void currentTable(Table table) {
Z
zhuangjiaju 已提交
284 285 286
        if (table == null) {
            return;
        }
Z
zhuangjiaju 已提交
287 288
        if (table.getTableNo() == null || table.getTableNo() <= 0) {
            table.setTableNo(0);
Z
zhuangjiaju 已提交
289
        }
Z
zhuangjiaju 已提交
290 291 292 293 294
        if (currentSheetHolder.getHasBeenInitializedTable().containsKey(table.getTableNo())) {
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("Table:{} is already existed", table.getTableNo());
            }
            currentTableHolder = currentSheetHolder.getHasBeenInitializedTable().get(table.getTableNo());
295
            currentTableHolder.setNewInitialization(Boolean.FALSE);
Z
zhuangjiaju 已提交
296 297 298 299
            currentConfigurationSelector = currentTableHolder;
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("CurrentConfigurationSelector is currentTableHolder");
            }
Z
zhuangjiaju 已提交
300 301
            return;
        }
Z
zhuangjiaju 已提交
302 303 304
        initCurrentTableHolder(table);
        initHead(currentTableHolder.getExcelHeadProperty());
    }
Z
zhuangjiaju 已提交
305

Z
zhuangjiaju 已提交
306
    private void initCurrentTableHolder(com.alibaba.excel.metadata.Table table) {
Z
zhuangjiaju 已提交
307
        currentTableHolder = new TableHolder(table, currentSheetHolder, currentWorkbookHolder);
308
        currentSheetHolder.getHasBeenInitializedTable().put(table.getTableNo(), currentTableHolder);
Z
zhuangjiaju 已提交
309 310 311
        currentConfigurationSelector = currentTableHolder;
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("CurrentConfigurationSelector is currentTableHolder");
clevertension's avatar
clevertension 已提交
312 313 314
        }
    }

Z
zhuangjiaju 已提交
315
    @Override
Z
zhuangjiaju 已提交
316 317
    public ConfigurationSelector currentConfigurationSelector() {
        return currentConfigurationSelector;
clevertension's avatar
clevertension 已提交
318 319 320
    }

    @Override
Z
zhuangjiaju 已提交
321 322
    public WorkbookHolder currentWorkbookHolder() {
        return currentWorkbookHolder;
clevertension's avatar
clevertension 已提交
323 324 325
    }

    @Override
Z
zhuangjiaju 已提交
326 327
    public SheetHolder currentSheetHolder() {
        return currentSheetHolder;
clevertension's avatar
clevertension 已提交
328 329 330
    }

    @Override
Z
zhuangjiaju 已提交
331 332
    public TableHolder currentTableHolder() {
        return currentTableHolder;
clevertension's avatar
clevertension 已提交
333
    }
Z
zhuangjiaju 已提交
334 335 336 337

    @Override
    public void finish() {
        try {
Z
zhuangjiaju 已提交
338 339
            currentWorkbookHolder.getWorkbook().write(currentWorkbookHolder.getOutputStream());
            currentWorkbookHolder.getWorkbook().close();
340 341 342 343 344 345 346
            if (currentWorkbookHolder.getAutoCloseStream()) {
                if (currentWorkbookHolder.getOutputStream() != null) {
                    currentWorkbookHolder.getOutputStream().close();
                }
                if (currentWorkbookHolder.getTemplateInputStream() != null) {
                    currentWorkbookHolder.getTemplateInputStream().close();
                }
Z
zhuangjiaju 已提交
347 348 349 350
            }
        } catch (IOException e) {
            throw new ExcelGenerateException("Can not close IO", e);
        }
351 352 353
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Finished write.");
        }
Z
zhuangjiaju 已提交
354
    }
clevertension's avatar
clevertension 已提交
355
}