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

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

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
10
import org.apache.poi.ss.usermodel.Workbook;
clevertension's avatar
clevertension 已提交
11
import org.apache.poi.ss.util.CellRangeAddress;
庄家钜's avatar
庄家钜 已提交
12
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
Z
zhuangjiaju 已提交
13 14
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
clevertension's avatar
clevertension 已提交
15

Z
zhuangjiaju 已提交
16
import com.alibaba.excel.exception.ExcelGenerateException;
Z
zhuangjiaju 已提交
17
import com.alibaba.excel.metadata.Head;
clevertension's avatar
clevertension 已提交
18
import com.alibaba.excel.util.WorkBookUtil;
19 20
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.handler.RowWriteHandler;
Z
zhuangjiaju 已提交
21 22
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.handler.WorkbookWriteHandler;
Z
zhuangjiaju 已提交
23
import com.alibaba.excel.write.handler.WriteHandler;
24 25 26 27 28 29 30 31
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 已提交
32 33 34 35 36 37 38

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

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

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

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

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

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

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

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

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

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

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

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

198 199
    public void initHead(ExcelWriteHeadProperty excelWriteHeadProperty) {
        if (!currentWriteHolder.needHead() || !currentWriteHolder.excelWriteHeadProperty().hasHead()) {
Z
zhuangjiaju 已提交
200 201
            return;
        }
Z
zhuangjiaju 已提交
202 203
        int newRowIndex = writeSheetHolder.getNewRowIndexAndStartDoWrite();
        newRowIndex += currentWriteHolder.relativeHeadRowIndex();
Z
zhuangjiaju 已提交
204
        // Combined head
Z
zhuangjiaju 已提交
205 206
        addMergedRegionToCurrentSheet(excelWriteHeadProperty, newRowIndex);
        for (int relativeRowIndex = 0, i = newRowIndex; i < excelWriteHeadProperty.getHeadRowNumber() + newRowIndex;
207
            i++, relativeRowIndex++) {
Z
zhuangjiaju 已提交
208
            beforeRowCreate(newRowIndex, relativeRowIndex);
209
            Row row = WorkBookUtil.createRow(writeSheetHolder.getSheet(), i);
210
            afterRowCreate(row, relativeRowIndex);
211
            addOneRowOfHeadDataToExcel(row, excelWriteHeadProperty.getHeadMap(), relativeRowIndex);
212 213 214 215
        }
    }

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

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

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

Z
zhuangjiaju 已提交
251 252 253 254 255 256
    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);
257 258 259 260
        }
    }

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

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

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

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

Z
zhuangjiaju 已提交
322
    @Override
323 324
    public WriteWorkbookHolder writeWorkbookHolder() {
        return writeWorkbookHolder;
clevertension's avatar
clevertension 已提交
325 326 327
    }

    @Override
328 329
    public WriteSheetHolder writeSheetHolder() {
        return writeSheetHolder;
clevertension's avatar
clevertension 已提交
330 331 332
    }

    @Override
333 334
    public WriteTableHolder writeTableHolder() {
        return writeTableHolder;
clevertension's avatar
clevertension 已提交
335 336 337
    }

    @Override
338 339
    public WriteHolder currentWriteHolder() {
        return currentWriteHolder;
clevertension's avatar
clevertension 已提交
340
    }
Z
zhuangjiaju 已提交
341 342 343

    @Override
    public void finish() {
344 345 346
        if (writeWorkbookHolder == null) {
            return;
        }
庄家钜's avatar
庄家钜 已提交
347

Z
zhuangjiaju 已提交
348
        try {
349 350
            writeWorkbookHolder.getWorkbook().write(writeWorkbookHolder.getOutputStream());
            writeWorkbookHolder.getWorkbook().close();
庄家钜's avatar
庄家钜 已提交
351 352 353 354 355 356 357 358 359 360
        } catch (Throwable t) {
            throwCanNotCloseIo(t);
        }
        try {
            Workbook workbook = writeWorkbookHolder.getWorkbook();
            if (workbook instanceof SXSSFWorkbook) {
                ((SXSSFWorkbook)workbook).dispose();
            }
        } catch (Throwable t) {
            throwCanNotCloseIo(t);
Z
zhuangjiaju 已提交
361 362 363 364 365
        }
        try {
            if (writeWorkbookHolder.getAutoCloseStream() && writeWorkbookHolder.getOutputStream() != null) {
                writeWorkbookHolder.getOutputStream().close();
            }
庄家钜's avatar
庄家钜 已提交
366 367
        } catch (Throwable t) {
            throwCanNotCloseIo(t);
Z
zhuangjiaju 已提交
368 369 370 371 372
        }
        try {
            if (writeWorkbookHolder.getAutoCloseStream() && writeWorkbookHolder.getTemplateInputStream() != null) {
                writeWorkbookHolder.getTemplateInputStream().close();
            }
庄家钜's avatar
庄家钜 已提交
373 374
        } catch (Throwable t) {
            throwCanNotCloseIo(t);
Z
zhuangjiaju 已提交
375 376 377 378 379
        }
        try {
            if (!writeWorkbookHolder.getAutoCloseStream() && writeWorkbookHolder.getFile() != null
                && writeWorkbookHolder.getOutputStream() != null) {
                writeWorkbookHolder.getOutputStream().close();
Z
zhuangjiaju 已提交
380
            }
庄家钜's avatar
庄家钜 已提交
381 382
        } catch (Throwable t) {
            throwCanNotCloseIo(t);
Z
zhuangjiaju 已提交
383
        }
384 385 386
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Finished write.");
        }
Z
zhuangjiaju 已提交
387
    }
388

庄家钜's avatar
庄家钜 已提交
389 390 391 392
    private void throwCanNotCloseIo(Throwable t) {
        throw new ExcelGenerateException("Can not close IO", t);
    }

393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411
    @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 已提交
412
}