WriteContextImpl.java 14.4 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.util.WorkBookUtil;
17 18
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.handler.RowWriteHandler;
Z
zhuangjiaju 已提交
19 20
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.handler.WorkbookWriteHandler;
Z
zhuangjiaju 已提交
21
import com.alibaba.excel.write.handler.WriteHandler;
22 23 24 25 26 27 28 29
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 已提交
30 31 32 33 34 35 36

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Z
zhuangjiaju 已提交
247 248 249 250 251 252
    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);
253 254 255 256
        }
    }

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

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

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

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

Z
zhuangjiaju 已提交
318
    @Override
319 320
    public WriteWorkbookHolder writeWorkbookHolder() {
        return writeWorkbookHolder;
clevertension's avatar
clevertension 已提交
321 322 323
    }

    @Override
324 325
    public WriteSheetHolder writeSheetHolder() {
        return writeSheetHolder;
clevertension's avatar
clevertension 已提交
326 327 328
    }

    @Override
329 330
    public WriteTableHolder writeTableHolder() {
        return writeTableHolder;
clevertension's avatar
clevertension 已提交
331 332 333
    }

    @Override
334 335
    public WriteHolder currentWriteHolder() {
        return currentWriteHolder;
clevertension's avatar
clevertension 已提交
336
    }
Z
zhuangjiaju 已提交
337 338 339 340

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