package foundation.io.file; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.math.BigDecimal; import java.util.Date; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import foundation.data.entity.Entity; import foundation.data.entity.EntitySet; import foundation.data.meta.field.FieldWriter; import foundation.data.meta.field.FieldsRuntime; import foundation.io.define.DataIO; import foundation.io.engine.ISheetWriter; import foundation.io.engine.IWorkBookWriter; import foundation.io.mapping.MappingsRuntime; import foundation.io.object.Headers; import foundation.io.object.Titles; import foundation.translator.ValueType; import foundation.util.MapList; public class BookBatchWriter extends IWorkBookWriter implements ISheetWriter { private File file; private int batchCount; private FileInputStream inputStream; private XSSFWorkbook workbook; private SXSSFWorkbook batchWorkbook; private MapList sheetList; private Sheet sheet; private int titleRowNo; private int dataRowNo; private CellStyle[] cellStyles; private int currentRowNo; private int columnCount; public BookBatchWriter(File file, int batchCount) throws IOException { this.file = file; this.batchCount = batchCount; inputStream = new FileInputStream(file); workbook = new XSSFWorkbook(inputStream); sheetList = new MapList(); for (Sheet sheet: workbook) { sheetList.add(sheet.getSheetName(), sheet); } } @Override public ISheetWriter openSheetWriter(DataIO dataIO) { this.titleRowNo = dataIO.getToTitleRowNo(); this.dataRowNo = dataIO.getToDataRowNo(); String sheetName = dataIO.getToName(); sheet = sheetList.get(sheetName); if (sheet == null) { sheet = sheetList.get(0); } if (sheet == null) { sheet = workbook.createSheet(sheetName); } currentRowNo = -1; return this; } @Override public void writeTitles(Titles titles) { Row titleRow = sheet.getRow(titleRowNo); if (titleRow == null) { titleRow = sheet.createRow(titleRowNo); } Cell cell; for (int i = 0; i < columnCount; i++) { cell = titleRow.getCell(i); if (cell == null) { cell = titleRow.createCell(i); } String title = titles.get(i); writeOneCell(cell, i, ValueType.String, title); } } @Override public Headers readHeaders() { // TODO Auto-generated method stub return null; } @Override public void parepareWriteData() { //1. createDataCellStyles(); //2. emptyDataArea(); //3. createStreamWorkbook(); } private void createDataCellStyles() { Row firstDataRow = sheet.getRow(dataRowNo); if (firstDataRow == null) { firstDataRow = sheet.createRow(dataRowNo); } cellStyles = new CellStyle[columnCount]; for (int i = 0; i < columnCount; i++) { Cell cell = firstDataRow.getCell(i); if (cell == null) { continue; } cellStyles[i] = cell.getCellStyle(); } } private void emptyDataArea() { int begin = Math.max(sheet.getFirstRowNum(), dataRowNo); int end = Math.min(sheet.getLastRowNum(), dataRowNo); for (int i = begin; i <= end; i++) { Row row = sheet.getRow(i); if (row != null) { sheet.removeRow(row); } } } private void createStreamWorkbook() { batchWorkbook = new SXSSFWorkbook(workbook, batchCount); batchWorkbook.setCompressTempFiles(false); sheet = batchWorkbook.getSheet(sheet.getSheetName()); } @Override public int writeData(EntitySet entitySet) { int result = 0; if (currentRowNo < 0) { currentRowNo = dataRowNo; } Row dataRow = null; Cell cell; FieldWriter fieldWriter; Object[] data; FieldsRuntime fields = entitySet.getEntityMeta(); ValueType[] valueTypes = fields.getValueTypes(); FieldWriter[] fieldWriters = fields.getWriters(); for (Entity entity: entitySet) { data = entity.getDataArray(); dataRow = sheet.createRow(currentRowNo); for (int i = 0; i < columnCount; i++) { cell = dataRow.getCell(i); if (cell == null) { cell = dataRow.createCell(i); } fieldWriter = fieldWriters[i]; Object value = fieldWriter.getValue(data[i]); writeOneCell(cell, i, valueTypes[i], value); } currentRowNo++; result++; } return result; } protected void writeOneCell(Cell cell, int idx, ValueType valueType, Object value) { CellStyle cellStyle = cellStyles[idx]; if (cellStyle != null) { cell.setCellStyle(cellStyle); } if (value == null) { return ; } if (ValueType.Decimal == valueType) { cell.setCellValue(((BigDecimal)value).doubleValue()); } else if (ValueType.Double == valueType) { cell.setCellValue((Double)value); } else if (ValueType.Int == valueType) { cell.setCellValue((Integer)value); } else if (ValueType.Long == valueType) { cell.setCellValue((Long)value); } else if (ValueType.Float == valueType) { cell.setCellValue((Float)value); } else if (ValueType.Date == valueType) { cell.setCellValue((Date)value); } else { cell.setCellValue(String.valueOf(value)); } } @Override public void close() { try { FileOutputStream outputStream = new FileOutputStream(file); try { // workbook.write(outputStream); // workbook.close(); batchWorkbook.write(outputStream); batchWorkbook.dispose(); batchWorkbook.close(); close = true; } finally { outputStream.close(); } } catch (Exception e) { logger.error("close work book error: {}", e.getMessage()); } try { workbook.close(); close = true; } catch (Exception e) { } } @Override public void setMappingRuntime(MappingsRuntime mappingsRuntime) { this.columnCount = mappingsRuntime.getToTitles().size(); } @Override public void writeErrorTitle() { // TODO Auto-generated method stub } @Override public int writeErrors(EntitySet entitySet) { // TODO Auto-generated method stub return 0; } }