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

import java.io.IOException;
4
import java.io.OutputStream;
clevertension's avatar
clevertension 已提交
5
import java.util.List;
Z
zhuangjiaju 已提交
6
import java.util.Map;
clevertension's avatar
clevertension 已提交
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;
11
import org.apache.poi.ss.usermodel.Workbook;
clevertension's avatar
clevertension 已提交
12
import org.apache.poi.ss.util.CellRangeAddress;
Z
zhuangjiaju 已提交
13 14
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
clevertension's avatar
clevertension 已提交
15

Z
zhuangjiaju 已提交
16
import com.alibaba.excel.enums.WriteLastRowType;
Z
zhuangjiaju 已提交
17
import com.alibaba.excel.exception.ExcelGenerateException;
Z
zhuangjiaju 已提交
18
import com.alibaba.excel.metadata.Head;
clevertension's avatar
clevertension 已提交
19
import com.alibaba.excel.util.WorkBookUtil;
20 21
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.handler.RowWriteHandler;
Z
zhuangjiaju 已提交
22 23
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.handler.WorkbookWriteHandler;
Z
zhuangjiaju 已提交
24
import com.alibaba.excel.write.handler.WriteHandler;
25 26 27 28 29 30 31 32
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.WriteTable;
import com.alibaba.excel.write.metadata.WriteWorkbook;
import com.alibaba.excel.write.metadata.holder.WriteHolder;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import com.alibaba.excel.write.property.ExcelWriteHeadProperty;
clevertension's avatar
clevertension 已提交
33 34 35 36 37 38 39

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

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

clevertension's avatar
clevertension 已提交
43
    /**
Z
zhuangjiaju 已提交
44
     * The Workbook currently written
clevertension's avatar
clevertension 已提交
45
     */
46
    private WriteWorkbookHolder writeWorkbookHolder;
clevertension's avatar
clevertension 已提交
47
    /**
Z
zhuangjiaju 已提交
48
     * Current sheet holder
clevertension's avatar
clevertension 已提交
49
     */
50
    private WriteSheetHolder writeSheetHolder;
clevertension's avatar
clevertension 已提交
51
    /**
Z
zhuangjiaju 已提交
52
     * The table currently written
clevertension's avatar
clevertension 已提交
53
     */
54
    private WriteTableHolder writeTableHolder;
clevertension's avatar
clevertension 已提交
55
    /**
Z
zhuangjiaju 已提交
56
     * Configuration of currently operated cell
clevertension's avatar
clevertension 已提交
57
     */
58
    private WriteHolder currentWriteHolder;
Z
zhuangjiaju 已提交
59

60 61
    public WriteContextImpl(WriteWorkbook writeWorkbook) {
        if (writeWorkbook == null) {
Z
zhuangjiaju 已提交
62 63
            throw new IllegalArgumentException("Workbook argument cannot be null");
        }
Z
zhuangjiaju 已提交
64 65 66
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Begin to Initialization 'WriteContextImpl'");
        }
67
        initCurrentWorkbookHolder(writeWorkbook);
Z
zhuangjiaju 已提交
68
        beforeWorkbookCreate();
Z
zhuangjiaju 已提交
69
        try {
70
            writeWorkbookHolder.setWorkbook(WorkBookUtil.createWorkBook(writeWorkbookHolder));
Z
zhuangjiaju 已提交
71
        } catch (Exception e) {
Z
zhuangjiaju 已提交
72 73
            throw new ExcelGenerateException("Create workbook failure", e);
        }
Z
zhuangjiaju 已提交
74
        afterWorkbookCreate();
Z
zhuangjiaju 已提交
75 76 77 78 79
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Initialization 'WriteContextImpl' complete");
        }
    }

Z
zhuangjiaju 已提交
80
    private void beforeWorkbookCreate() {
81
        List<WriteHandler> handlerList = currentWriteHolder.writeHandlerMap().get(WorkbookWriteHandler.class);
Z
zhuangjiaju 已提交
82 83 84 85 86 87 88 89 90 91 92
        if (handlerList == null || handlerList.isEmpty()) {
            return;
        }
        for (WriteHandler writeHandler : handlerList) {
            if (writeHandler instanceof WorkbookWriteHandler) {
                ((WorkbookWriteHandler)writeHandler).beforeWorkbookCreate();
            }
        }
    }

    private void afterWorkbookCreate() {
93
        List<WriteHandler> handlerList = currentWriteHolder.writeHandlerMap().get(WorkbookWriteHandler.class);
Z
zhuangjiaju 已提交
94 95 96 97 98
        if (handlerList == null || handlerList.isEmpty()) {
            return;
        }
        for (WriteHandler writeHandler : handlerList) {
            if (writeHandler instanceof WorkbookWriteHandler) {
99
                ((WorkbookWriteHandler)writeHandler).afterWorkbookCreate(writeWorkbookHolder);
Z
zhuangjiaju 已提交
100 101 102 103
            }
        }
    }

104 105 106
    private void initCurrentWorkbookHolder(WriteWorkbook writeWorkbook) {
        writeWorkbookHolder = new WriteWorkbookHolder(writeWorkbook);
        currentWriteHolder = writeWorkbookHolder;
Z
zhuangjiaju 已提交
107
        if (LOGGER.isDebugEnabled()) {
108
            LOGGER.debug("CurrentConfiguration is writeWorkbookHolder");
Z
zhuangjiaju 已提交
109 110
        }
    }
clevertension's avatar
clevertension 已提交
111 112

    /**
113
     * @param writeSheet
clevertension's avatar
clevertension 已提交
114 115
     */
    @Override
116 117
    public void currentSheet(WriteSheet writeSheet) {
        if (writeSheet == null) {
Z
zhuangjiaju 已提交
118 119
            throw new IllegalArgumentException("Sheet argument cannot be null");
        }
120
        if (writeSheet.getSheetNo() == null || writeSheet.getSheetNo() <= 0) {
Z
zhuangjiaju 已提交
121
            LOGGER.info("Sheet number is null");
122
            writeSheet.setSheetNo(0);
Z
zhuangjiaju 已提交
123
        }
124
        if (writeWorkbookHolder.getHasBeenInitializedSheet().containsKey(writeSheet.getSheetNo())) {
Z
zhuangjiaju 已提交
125
            if (LOGGER.isDebugEnabled()) {
126
                LOGGER.debug("Sheet:{} is already existed", writeSheet.getSheetNo());
clevertension's avatar
clevertension 已提交
127
            }
128 129 130 131
            writeSheetHolder = writeWorkbookHolder.getHasBeenInitializedSheet().get(writeSheet.getSheetNo());
            writeSheetHolder.setNewInitialization(Boolean.FALSE);
            writeTableHolder = null;
            currentWriteHolder = writeSheetHolder;
Z
zhuangjiaju 已提交
132
            if (LOGGER.isDebugEnabled()) {
133
                LOGGER.debug("CurrentConfiguration is writeSheetHolder");
Z
zhuangjiaju 已提交
134 135
            }
            return;
clevertension's avatar
clevertension 已提交
136
        }
137
        initCurrentSheetHolder(writeSheet);
Z
zhuangjiaju 已提交
138
        beforeSheetCreate();
Z
zhuangjiaju 已提交
139
        // Initialization current sheet
140
        initSheet();
Z
zhuangjiaju 已提交
141 142 143 144
        afterSheetCreate();
    }

    private void beforeSheetCreate() {
145
        List<WriteHandler> handlerList = currentWriteHolder.writeHandlerMap().get(SheetWriteHandler.class);
Z
zhuangjiaju 已提交
146 147 148 149 150
        if (handlerList == null || handlerList.isEmpty()) {
            return;
        }
        for (WriteHandler writeHandler : handlerList) {
            if (writeHandler instanceof SheetWriteHandler) {
151
                ((SheetWriteHandler)writeHandler).beforeSheetCreate(writeWorkbookHolder, writeSheetHolder);
Z
zhuangjiaju 已提交
152 153 154 155 156
            }
        }
    }

    private void afterSheetCreate() {
157
        List<WriteHandler> handlerList = currentWriteHolder.writeHandlerMap().get(SheetWriteHandler.class);
Z
zhuangjiaju 已提交
158 159 160 161 162
        if (handlerList == null || handlerList.isEmpty()) {
            return;
        }
        for (WriteHandler writeHandler : handlerList) {
            if (writeHandler instanceof SheetWriteHandler) {
163
                ((SheetWriteHandler)writeHandler).afterSheetCreate(writeWorkbookHolder, writeSheetHolder);
Z
zhuangjiaju 已提交
164 165
            }
        }
166 167 168
        if (null != writeWorkbookHolder.getWriteWorkbook().getWriteHandler()) {
            writeWorkbookHolder.getWriteWorkbook().getWriteHandler().sheet(writeSheetHolder.getSheetNo(),
                writeSheetHolder.getSheet());
169
        }
Z
zhuangjiaju 已提交
170
    }
clevertension's avatar
clevertension 已提交
171

172 173 174 175 176
    private void initCurrentSheetHolder(WriteSheet writeSheet) {
        writeSheetHolder = new WriteSheetHolder(writeSheet, writeWorkbookHolder);
        writeWorkbookHolder.getHasBeenInitializedSheet().put(writeSheet.getSheetNo(), writeSheetHolder);
        writeTableHolder = null;
        currentWriteHolder = writeSheetHolder;
Z
zhuangjiaju 已提交
177
        if (LOGGER.isDebugEnabled()) {
178
            LOGGER.debug("CurrentConfiguration is writeSheetHolder");
Z
zhuangjiaju 已提交
179
        }
clevertension's avatar
clevertension 已提交
180 181
    }

182
    private void initSheet() {
Z
zhuangjiaju 已提交
183 184
        Sheet currentSheet;
        try {
185
            currentSheet = writeWorkbookHolder.getWorkbook().getSheetAt(writeSheetHolder.getSheetNo());
Z
zhuangjiaju 已提交
186 187
        } catch (Exception e) {
            if (LOGGER.isDebugEnabled()) {
188
                LOGGER.debug("Can not find sheet:{} ,now create it", writeSheetHolder.getSheetNo());
Z
zhuangjiaju 已提交
189
            }
190
            currentSheet = WorkBookUtil.createSheet(writeWorkbookHolder.getWorkbook(), writeSheetHolder.getSheetName());
Z
zhuangjiaju 已提交
191
        }
192
        writeSheetHolder.setSheet(currentSheet);
Z
zhuangjiaju 已提交
193
        // Initialization head
194
        initHead(writeSheetHolder.excelWriteHeadProperty());
clevertension's avatar
clevertension 已提交
195 196
    }

197 198
    public void initHead(ExcelWriteHeadProperty excelWriteHeadProperty) {
        if (!currentWriteHolder.needHead() || !currentWriteHolder.excelWriteHeadProperty().hasHead()) {
Z
zhuangjiaju 已提交
199 200
            return;
        }
201
        int lastRowNum = writeSheetHolder.getSheet().getLastRowNum();
Z
zhuangjiaju 已提交
202
        // 'lastRowNum' doesn't matter if it has one or zero,is's zero
Z
zhuangjiaju 已提交
203 204
        if (WriteLastRowType.HAVE_DATA == writeSheetHolder.getWriteLastRowType()) {
            lastRowNum++;
Z
zhuangjiaju 已提交
205 206
        }
        writeSheetHolder.setWriteLastRowType(WriteLastRowType.HAVE_DATA);
207
        int rowIndex = lastRowNum + currentWriteHolder.relativeHeadRowIndex();
Z
zhuangjiaju 已提交
208
        // Combined head
209 210
        addMergedRegionToCurrentSheet(excelWriteHeadProperty, rowIndex);
        for (int relativeRowIndex = 0, i = rowIndex; i < excelWriteHeadProperty.getHeadRowNumber() + rowIndex;
211 212
            i++, relativeRowIndex++) {
            beforeRowCreate(rowIndex, relativeRowIndex);
213
            Row row = WorkBookUtil.createRow(writeSheetHolder.getSheet(), i);
214
            afterRowCreate(row, relativeRowIndex);
215
            addOneRowOfHeadDataToExcel(row, excelWriteHeadProperty.getHeadMap(), relativeRowIndex);
216 217 218 219
        }
    }

    private void beforeRowCreate(int rowIndex, int relativeRowIndex) {
220
        List<WriteHandler> handlerList = currentWriteHolder.writeHandlerMap().get(RowWriteHandler.class);
221 222 223 224 225
        if (handlerList == null || handlerList.isEmpty()) {
            return;
        }
        for (WriteHandler writeHandler : handlerList) {
            if (writeHandler instanceof RowWriteHandler) {
226
                ((RowWriteHandler)writeHandler).beforeRowCreate(writeSheetHolder, writeTableHolder, rowIndex,
227 228
                    relativeRowIndex, true);
            }
clevertension's avatar
clevertension 已提交
229 230 231
        }
    }

232
    private void afterRowCreate(Row row, int relativeRowIndex) {
233
        List<WriteHandler> handlerList = currentWriteHolder.writeHandlerMap().get(RowWriteHandler.class);
234 235 236 237 238
        if (handlerList == null || handlerList.isEmpty()) {
            return;
        }
        for (WriteHandler writeHandler : handlerList) {
            if (writeHandler instanceof RowWriteHandler) {
239
                ((RowWriteHandler)writeHandler).afterRowCreate(writeSheetHolder, writeTableHolder, row,
240 241 242
                    relativeRowIndex, true);
            }
        }
243 244
        if (null != writeWorkbookHolder.getWriteWorkbook().getWriteHandler()) {
            writeWorkbookHolder.getWriteWorkbook().getWriteHandler().row(row.getRowNum(), row);
245 246 247
        }
    }

248 249 250
    private void addMergedRegionToCurrentSheet(ExcelWriteHeadProperty excelWriteHeadProperty, int rowIndex) {
        for (com.alibaba.excel.metadata.CellRange cellRangeModel : excelWriteHeadProperty.headCellRangeList()) {
            writeSheetHolder.getSheet().addMergedRegion(new CellRangeAddress(cellRangeModel.getFirstRow() + rowIndex,
251
                cellRangeModel.getLastRow() + rowIndex, cellRangeModel.getFirstCol(), cellRangeModel.getLastCol()));
clevertension's avatar
clevertension 已提交
252 253 254
        }
    }

Z
zhuangjiaju 已提交
255 256 257 258 259 260
    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);
261 262 263 264
        }
    }

    private void beforeCellCreate(Row row, Head head, int relativeRowIndex) {
265
        List<WriteHandler> handlerList = currentWriteHolder.writeHandlerMap().get(CellWriteHandler.class);
266 267 268 269 270
        if (handlerList == null || handlerList.isEmpty()) {
            return;
        }
        for (WriteHandler writeHandler : handlerList) {
            if (writeHandler instanceof CellWriteHandler) {
271
                ((CellWriteHandler)writeHandler).beforeCellCreate(writeSheetHolder, writeTableHolder, row, head,
272 273 274 275 276 277
                    relativeRowIndex, true);
            }
        }
    }

    private void afterCellCreate(Head head, Cell cell, int relativeRowIndex) {
278
        List<WriteHandler> handlerList = currentWriteHolder.writeHandlerMap().get(CellWriteHandler.class);
279 280 281 282 283
        if (handlerList == null || handlerList.isEmpty()) {
            return;
        }
        for (WriteHandler writeHandler : handlerList) {
            if (writeHandler instanceof CellWriteHandler) {
284
                ((CellWriteHandler)writeHandler).afterCellCreate(writeSheetHolder, writeTableHolder, cell, head,
285 286 287
                    relativeRowIndex, true);
            }
        }
288 289
        if (null != writeWorkbookHolder.getWriteWorkbook().getWriteHandler()) {
            writeWorkbookHolder.getWriteWorkbook().getWriteHandler().cell(cell.getRowIndex(), cell);
clevertension's avatar
clevertension 已提交
290 291 292 293
        }
    }

    @Override
294 295
    public void currentTable(WriteTable writeTable) {
        if (writeTable == null) {
Z
zhuangjiaju 已提交
296 297
            return;
        }
298 299
        if (writeTable.getTableNo() == null || writeTable.getTableNo() <= 0) {
            writeTable.setTableNo(0);
Z
zhuangjiaju 已提交
300
        }
301
        if (writeSheetHolder.getHasBeenInitializedTable().containsKey(writeTable.getTableNo())) {
Z
zhuangjiaju 已提交
302
            if (LOGGER.isDebugEnabled()) {
303
                LOGGER.debug("Table:{} is already existed", writeTable.getTableNo());
Z
zhuangjiaju 已提交
304
            }
305 306 307
            writeTableHolder = writeSheetHolder.getHasBeenInitializedTable().get(writeTable.getTableNo());
            writeTableHolder.setNewInitialization(Boolean.FALSE);
            currentWriteHolder = writeTableHolder;
Z
zhuangjiaju 已提交
308
            if (LOGGER.isDebugEnabled()) {
309
                LOGGER.debug("CurrentConfiguration is writeTableHolder");
Z
zhuangjiaju 已提交
310
            }
Z
zhuangjiaju 已提交
311 312
            return;
        }
313 314
        initCurrentTableHolder(writeTable);
        initHead(writeTableHolder.excelWriteHeadProperty());
Z
zhuangjiaju 已提交
315
    }
Z
zhuangjiaju 已提交
316

317 318 319 320
    private void initCurrentTableHolder(WriteTable writeTable) {
        writeTableHolder = new WriteTableHolder(writeTable, writeSheetHolder, writeWorkbookHolder);
        writeSheetHolder.getHasBeenInitializedTable().put(writeTable.getTableNo(), writeTableHolder);
        currentWriteHolder = writeTableHolder;
Z
zhuangjiaju 已提交
321
        if (LOGGER.isDebugEnabled()) {
322
            LOGGER.debug("CurrentConfiguration is writeTableHolder");
clevertension's avatar
clevertension 已提交
323 324 325
        }
    }

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

    @Override
332 333
    public WriteSheetHolder writeSheetHolder() {
        return writeSheetHolder;
clevertension's avatar
clevertension 已提交
334 335 336
    }

    @Override
337 338
    public WriteTableHolder writeTableHolder() {
        return writeTableHolder;
clevertension's avatar
clevertension 已提交
339 340 341
    }

    @Override
342 343
    public WriteHolder currentWriteHolder() {
        return currentWriteHolder;
clevertension's avatar
clevertension 已提交
344
    }
Z
zhuangjiaju 已提交
345 346 347

    @Override
    public void finish() {
348 349 350
        if (writeWorkbookHolder == null) {
            return;
        }
Z
zhuangjiaju 已提交
351
        try {
352 353 354 355 356
            writeWorkbookHolder.getWorkbook().write(writeWorkbookHolder.getOutputStream());
            writeWorkbookHolder.getWorkbook().close();
            if (writeWorkbookHolder.getAutoCloseStream()) {
                if (writeWorkbookHolder.getOutputStream() != null) {
                    writeWorkbookHolder.getOutputStream().close();
357
                }
358 359
                if (writeWorkbookHolder.getTemplateInputStream() != null) {
                    writeWorkbookHolder.getTemplateInputStream().close();
360
                }
Z
zhuangjiaju 已提交
361 362 363 364
            } else {
                if (writeWorkbookHolder.getFile() != null && writeWorkbookHolder.getOutputStream() != null) {
                    writeWorkbookHolder.getOutputStream().close();
                }
Z
zhuangjiaju 已提交
365 366 367 368
            }
        } catch (IOException e) {
            throw new ExcelGenerateException("Can not close IO", e);
        }
369 370 371
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Finished write.");
        }
Z
zhuangjiaju 已提交
372
    }
373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392

    @Override
    public Sheet getCurrentSheet() {
        return writeSheetHolder.getSheet();
    }

    @Override
    public boolean needHead() {
        return writeSheetHolder.needHead();
    }

    @Override
    public OutputStream getOutputStream() {
        return writeWorkbookHolder.getOutputStream();
    }

    @Override
    public Workbook getWorkbook() {
        return writeWorkbookHolder.getWorkbook();
    }
clevertension's avatar
clevertension 已提交
393
}