WriteContextImpl.java 14.6 KB
Newer Older
clevertension's avatar
clevertension 已提交
1 2 3 4 5 6 7 8 9
package com.alibaba.excel.context;

import java.io.IOException;
import java.util.List;

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

Z
zhuangjiaju 已提交
13
import com.alibaba.excel.exception.ExcelGenerateException;
clevertension's avatar
clevertension 已提交
14
import com.alibaba.excel.metadata.ExcelHeadProperty;
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;
clevertension's avatar
clevertension 已提交
21
import com.alibaba.excel.util.WorkBookUtil;
22 23
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.handler.RowWriteHandler;
Z
zhuangjiaju 已提交
24 25
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.handler.WorkbookWriteHandler;
Z
zhuangjiaju 已提交
26
import com.alibaba.excel.write.handler.WriteHandler;
clevertension's avatar
clevertension 已提交
27 28 29 30 31 32 33

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

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

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

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

Z
zhuangjiaju 已提交
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
    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 已提交
98
    private void initCurrentWorkbookHolder(com.alibaba.excel.metadata.Workbook workbook) {
99
        currentWorkbookHolder = new WorkbookHolder(workbook);
Z
zhuangjiaju 已提交
100 101 102 103 104
        currentConfigurationSelector = currentWorkbookHolder;
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("CurrentConfigurationSelector is currentWorkbookHolder");
        }
    }
clevertension's avatar
clevertension 已提交
105 106 107 108 109 110

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

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

Z
zhuangjiaju 已提交
175
    private void initSheet(com.alibaba.excel.metadata.Sheet sheet) {
Z
zhuangjiaju 已提交
176 177 178 179 180 181 182 183
        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 已提交
184
        }
Z
zhuangjiaju 已提交
185 186
        currentSheetHolder.setSheet(currentSheet);
        // Initialization head
187 188
        currentSheetHolder
            .setExcelHeadProperty(new ExcelHeadProperty(currentSheetHolder.getClazz(), currentSheetHolder.getHead()));
Z
zhuangjiaju 已提交
189
        // Initialization head
Z
zhuangjiaju 已提交
190
        initHead(currentSheetHolder.getExcelHeadProperty());
clevertension's avatar
clevertension 已提交
191 192
    }

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

    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 已提交
220 221 222
        }
    }

223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
    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 已提交
240
        for (com.alibaba.excel.metadata.CellRange cellRangeModel : excelHeadProperty.getCellRangeModels()) {
241 242
            currentSheetHolder.getSheet().addMergedRegion(new CellRangeAddress(cellRangeModel.getFirstRow() + rowIndex,
                cellRangeModel.getLastRow() + rowIndex, cellRangeModel.getFirstCol(), cellRangeModel.getLastCol()));
clevertension's avatar
clevertension 已提交
243 244 245
        }
    }

246
    private void addOneRowOfHeadDataToExcel(Row row, List<Head> headList, int relativeRowIndex) {
Z
zhuangjiaju 已提交
247 248
        for (int i = 0; i < headList.size(); i++) {
            Head head = headList.get(i);
249
            beforeCellCreate(row, headList.get(i), relativeRowIndex);
Z
zhuangjiaju 已提交
250
            Cell cell = WorkBookUtil.createCell(row, i, head.getHeadName(i));
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 279 280
            afterCellCreate(headList.get(i), cell, relativeRowIndex);
        }
    }

    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 已提交
281 282 283 284 285
        }
    }

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

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

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

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

    @Override
Z
zhuangjiaju 已提交
331 332
    public SheetHolder currentSheetHolder() {
        return currentSheetHolder;
clevertension's avatar
clevertension 已提交
333 334 335
    }

    @Override
Z
zhuangjiaju 已提交
336 337
    public TableHolder currentTableHolder() {
        return currentTableHolder;
clevertension's avatar
clevertension 已提交
338
    }
Z
zhuangjiaju 已提交
339 340 341 342

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