ExcelBuilderImpl.java 11.3 KB
Newer Older
J
update  
jipengfei.jpf 已提交
1 2
package com.alibaba.excel.write;

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

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
10
import org.apache.poi.ss.usermodel.Sheet;
clevertension's avatar
clevertension 已提交
11 12
import org.apache.poi.ss.util.CellRangeAddress;

13
import com.alibaba.excel.context.WriteContext;
clevertension's avatar
clevertension 已提交
14 15
import com.alibaba.excel.context.WriteContextImpl;
import com.alibaba.excel.converters.Converter;
Z
zhuangjiaju 已提交
16
import com.alibaba.excel.exception.ExcelDataConvertException;
Z
zhuangjiaju 已提交
17
import com.alibaba.excel.metadata.CellData;
18
import com.alibaba.excel.metadata.Head;
Z
zhuangjiaju 已提交
19
import com.alibaba.excel.metadata.property.ExcelContentProperty;
20
import com.alibaba.excel.util.CollectionUtils;
21
import com.alibaba.excel.util.FileUtils;
22
import com.alibaba.excel.util.WorkBookUtil;
23 24 25
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.handler.RowWriteHandler;
import com.alibaba.excel.write.handler.WriteHandler;
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;
J
update  
jipengfei.jpf 已提交
30

clevertension's avatar
clevertension 已提交
31
import net.sf.cglib.beans.BeanMap;
32

J
update  
jipengfei.jpf 已提交
33 34 35
/**
 * @author jipengfei
 */
Z
zhuangjiaju 已提交
36
public class ExcelBuilderImpl implements ExcelBuilder {
Z
zhuangjiaju 已提交
37

38
    private WriteContext context;
Z
zhuangjiaju 已提交
39

40 41 42 43
    public ExcelBuilderImpl(WriteWorkbook writeWorkbook) {
        // Create temporary cache directory at initialization time to avoid POI concurrent write bugs
        FileUtils.createPoiFilesDirectory();
        context = new WriteContextImpl(writeWorkbook);
J
update  
jipengfei.jpf 已提交
44 45
    }

Z
zhuangjiaju 已提交
46
    private void doAddContent(List data) {
47 48 49
        if (CollectionUtils.isEmpty(data)) {
            return;
        }
50
        Sheet currentSheet = context.writeSheetHolder().getSheet();
Z
zhuangjiaju 已提交
51
        int rowNum = currentSheet.getLastRowNum();
52 53
        if (context.currentWriteHolder().isNew()) {
            rowNum += context.currentWriteHolder().relativeHeadRowIndex();
54
        }
55 56 57
        for (int relativeRowIndex = 0; relativeRowIndex < data.size(); relativeRowIndex++) {
            int n = relativeRowIndex + rowNum + 1;
            addOneRowOfDataToExcel(data.get(relativeRowIndex), n, relativeRowIndex);
J
update  
jipengfei.jpf 已提交
58 59 60
        }
    }

61
    @Override
62 63
    public void addContent(List data, WriteSheet writeSheet) {
        addContent(data, writeSheet, null);
J
update  
jipengfei.jpf 已提交
64 65
    }

66
    @Override
67 68 69
    public void addContent(List data, WriteSheet writeSheet, WriteTable writeTable) {
        context.currentSheet(writeSheet);
        context.currentTable(writeTable);
Z
zhuangjiaju 已提交
70
        doAddContent(data);
J
update  
jipengfei.jpf 已提交
71 72
    }

73
    @Override
Z
zhuangjiaju 已提交
74 75
    public void finish() {
        context.finish();
76 77
    }

78
    @Override
Z
zhuangjiaju 已提交
79 80
    public void merge(int firstRow, int lastRow, int firstCol, int lastCol) {
        CellRangeAddress cra = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
81
        context.writeSheetHolder().getSheet().addMergedRegion(cra);
Z
zhuangjiaju 已提交
82 83
    }

84 85
    private void addOneRowOfDataToExcel(Object oneRowData, int n, int relativeRowIndex) {
        beforeRowCreate(n, relativeRowIndex);
86
        Row row = WorkBookUtil.createRow(context.writeSheetHolder().getSheet(), n);
87
        afterRowCreate(row, relativeRowIndex);
Z
zhuangjiaju 已提交
88
        if (oneRowData instanceof List) {
89
            addBasicTypeToExcel((List)oneRowData, row, relativeRowIndex);
Z
zhuangjiaju 已提交
90
        } else {
91
            addJavaObjectToExcel(oneRowData, row, relativeRowIndex);
Z
zhuangjiaju 已提交
92
        }
J
update  
jipengfei.jpf 已提交
93 94
    }

95
    private void beforeRowCreate(int rowIndex, int relativeRowIndex) {
96
        List<WriteHandler> handlerList = context.currentWriteHolder().writeHandlerMap().get(RowWriteHandler.class);
97 98 99 100 101
        if (handlerList == null || handlerList.isEmpty()) {
            return;
        }
        for (WriteHandler writeHandler : handlerList) {
            if (writeHandler instanceof RowWriteHandler) {
102 103
                ((RowWriteHandler)writeHandler).beforeRowCreate(context.writeSheetHolder(), context.writeTableHolder(),
                    rowIndex, relativeRowIndex, false);
104 105 106 107 108
            }
        }
    }

    private void afterRowCreate(Row row, int relativeRowIndex) {
109
        List<WriteHandler> handlerList = context.currentWriteHolder().writeHandlerMap().get(RowWriteHandler.class);
110 111 112 113 114
        if (handlerList == null || handlerList.isEmpty()) {
            return;
        }
        for (WriteHandler writeHandler : handlerList) {
            if (writeHandler instanceof RowWriteHandler) {
115 116
                ((RowWriteHandler)writeHandler).afterRowCreate(context.writeSheetHolder(), context.writeTableHolder(),
                    row, relativeRowIndex, false);
117 118
            }
        }
119 120
        if (null != context.writeWorkbookHolder().getWriteWorkbook().getWriteHandler()) {
            context.writeWorkbookHolder().getWriteWorkbook().getWriteHandler().row(row.getRowNum(), row);
121 122 123 124
        }
    }

    private void addBasicTypeToExcel(List<Object> oneRowData, Row row, int relativeRowIndex) {
125 126 127
        if (CollectionUtils.isEmpty(oneRowData)) {
            return;
        }
128
        Map<Integer, Head> headMap = context.currentWriteHolder().excelWriteHeadProperty().getHeadMap();
Z
zhuangjiaju 已提交
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
        int dataIndex = 0;
        int cellIndex = 0;
        for (Map.Entry<Integer, Head> entry : headMap.entrySet()) {
            if (dataIndex >= oneRowData.size()) {
                return;
            }
            cellIndex = entry.getKey();
            Head head = entry.getValue();
            doAddBasicTypeToExcel(oneRowData, head, row, relativeRowIndex, dataIndex++, cellIndex);
        }
        // Finish
        if (dataIndex >= oneRowData.size()) {
            return;
        }
        if (cellIndex != 0) {
            cellIndex++;
        }
        for (int i = 0; i < oneRowData.size() - dataIndex; i++) {
            doAddBasicTypeToExcel(oneRowData, null, row, relativeRowIndex, dataIndex++, cellIndex++);
J
update  
jipengfei.jpf 已提交
148 149 150
        }
    }

Z
zhuangjiaju 已提交
151 152 153 154 155
    private void doAddBasicTypeToExcel(List<Object> oneRowData, Head head, Row row, int relativeRowIndex, int dataIndex,
        int cellIndex) {
        beforeCellCreate(row, head, relativeRowIndex);
        Cell cell = WorkBookUtil.createCell(row, cellIndex);
        Object value = oneRowData.get(dataIndex);
156
        converterAndSet(context.currentWriteHolder(), value.getClass(), cell, value, null);
Z
zhuangjiaju 已提交
157 158 159
        afterCellCreate(head, cell, relativeRowIndex);
    }

160
    private void addJavaObjectToExcel(Object oneRowData, Row row, int relativeRowIndex) {
161
        WriteHolder currentWriteHolder = context.currentWriteHolder();
162
        BeanMap beanMap = BeanMap.create(oneRowData);
Z
zhuangjiaju 已提交
163
        Set<String> beanMapHandledSet = new HashSet<String>();
164
        Map<Integer, Head> headMap = context.currentWriteHolder().excelWriteHeadProperty().getHeadMap();
Z
zhuangjiaju 已提交
165
        Map<Integer, ExcelContentProperty> contentPropertyMap =
166
            context.currentWriteHolder().excelWriteHeadProperty().getContentPropertyMap();
Z
zhuangjiaju 已提交
167 168 169 170 171 172 173 174 175
        int cellIndex = 0;
        for (Map.Entry<Integer, ExcelContentProperty> entry : contentPropertyMap.entrySet()) {
            cellIndex = entry.getKey();
            ExcelContentProperty excelContentProperty = entry.getValue();
            String name = excelContentProperty.getField().getName();
            if (!beanMap.containsKey(name)) {
                continue;
            }
            Head head = headMap.get(cellIndex);
176
            beforeCellCreate(row, head, relativeRowIndex);
Z
zhuangjiaju 已提交
177 178
            Cell cell = WorkBookUtil.createCell(row, cellIndex);
            Object value = beanMap.get(name);
179
            converterAndSet(currentWriteHolder, excelContentProperty.getField().getType(), cell, value,
Z
zhuangjiaju 已提交
180
                excelContentProperty);
181
            afterCellCreate(head, cell, relativeRowIndex);
Z
zhuangjiaju 已提交
182
            beanMapHandledSet.add(name);
Z
zhuangjiaju 已提交
183 184
        }
        // Finish
Z
zhuangjiaju 已提交
185
        if (beanMapHandledSet.size() == beanMap.size()) {
Z
zhuangjiaju 已提交
186
            return;
J
update  
jipengfei.jpf 已提交
187
        }
Z
zhuangjiaju 已提交
188 189 190
        if (cellIndex != 0) {
            cellIndex++;
        }
Z
zhuangjiaju 已提交
191 192 193 194 195
        Set<Map.Entry<String, Object>> entrySet = beanMap.entrySet();
        for (Map.Entry<String, Object> entry : entrySet) {
            if (entry.getValue() == null || beanMapHandledSet.contains(entry.getKey())) {
                continue;
            }
Z
zhuangjiaju 已提交
196 197
            beforeCellCreate(row, null, relativeRowIndex);
            Cell cell = WorkBookUtil.createCell(row, cellIndex++);
198
            converterAndSet(currentWriteHolder, entry.getValue().getClass(), cell, entry.getValue(), null);
Z
zhuangjiaju 已提交
199 200 201 202
            afterCellCreate(null, cell, relativeRowIndex);
        }
    }

203
    private void beforeCellCreate(Row row, Head head, int relativeRowIndex) {
204
        List<WriteHandler> handlerList = context.currentWriteHolder().writeHandlerMap().get(CellWriteHandler.class);
205 206 207 208 209
        if (handlerList == null || handlerList.isEmpty()) {
            return;
        }
        for (WriteHandler writeHandler : handlerList) {
            if (writeHandler instanceof CellWriteHandler) {
210 211
                ((CellWriteHandler)writeHandler).beforeCellCreate(context.writeSheetHolder(),
                    context.writeTableHolder(), row, head, relativeRowIndex, false);
212 213 214 215 216 217
            }
        }

    }

    private void afterCellCreate(Head head, Cell cell, int relativeRowIndex) {
218
        List<WriteHandler> handlerList = context.currentWriteHolder().writeHandlerMap().get(CellWriteHandler.class);
219 220 221 222 223
        if (handlerList == null || handlerList.isEmpty()) {
            return;
        }
        for (WriteHandler writeHandler : handlerList) {
            if (writeHandler instanceof CellWriteHandler) {
224 225
                ((CellWriteHandler)writeHandler).afterCellCreate(context.writeSheetHolder(), context.writeTableHolder(),
                    cell, head, relativeRowIndex, false);
226 227
            }
        }
228 229
        if (null != context.writeWorkbookHolder().getWriteWorkbook().getWriteHandler()) {
            context.writeWorkbookHolder().getWriteWorkbook().getWriteHandler().cell(cell.getRowIndex(), cell);
230 231 232
        }
    }

233 234
    private void converterAndSet(WriteHolder currentWriteHolder, Class clazz, Cell cell, Object value,
        ExcelContentProperty excelContentProperty) {
Z
zhuangjiaju 已提交
235 236 237
        if (value == null) {
            return;
        }
238
        Converter converter = currentWriteHolder.converterMap().get(clazz);
Z
zhuangjiaju 已提交
239 240 241
        if (converter == null) {
            throw new ExcelDataConvertException(
                "Can not find 'Converter' support class " + clazz.getSimpleName() + ".");
clevertension's avatar
clevertension 已提交
242
        }
J
update  
jipengfei.jpf 已提交
243

244
        CellData cellData;
Z
zhuangjiaju 已提交
245
        try {
Z
zhuangjiaju 已提交
246
            cellData = converter.convertToExcelData(value, excelContentProperty);
Z
zhuangjiaju 已提交
247 248 249
        } catch (Exception e) {
            throw new ExcelDataConvertException("Convert data:" + value + " error,at row:" + cell.getRow().getRowNum(),
                e);
250
        }
Z
zhuangjiaju 已提交
251 252 253 254
        if (cellData == null || cellData.getType() == null) {
            throw new ExcelDataConvertException(
                "Convert data:" + value + " return null,at row:" + cell.getRow().getRowNum());
        }
255 256 257
        if (cellData.getFormula() != null && cellData.getFormula()) {
            cell.setCellFormula(cellData.getFormulaValue());
        }
Z
zhuangjiaju 已提交
258 259
        switch (cellData.getType()) {
            case STRING:
260
                cell.setCellValue(cellData.getStringValue());
Z
zhuangjiaju 已提交
261 262
                return;
            case BOOLEAN:
263
                cell.setCellValue(cellData.getBooleanValue());
Z
zhuangjiaju 已提交
264 265
                return;
            case NUMBER:
266
                cell.setCellValue(cellData.getDoubleValue());
Z
zhuangjiaju 已提交
267 268 269 270
                return;
            default:
                throw new ExcelDataConvertException("Not supported data:" + value + " return type:" + cell.getCellType()
                    + "at row:" + cell.getRow().getRowNum());
J
update  
jipengfei.jpf 已提交
271 272 273
        }
    }
}