package com.wb.excel.api; import com.wb.excel.api.annotation.ColumnDescription; import com.wb.excel.api.datatable.WCell; import com.wb.excel.api.datatable.WColumn; import com.wb.excel.api.datatable.WSheet; import com.wb.excel.api.enumeration.DataType; import com.wb.excel.api.enumeration.Status; import com.wb.excel.api.style.*; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.*; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.lang.reflect.Field; import java.util.HashSet; import java.util.Set; /** * Excel帮助类. *

* Created on 2014/9/27. * * @author * @since 0.1.0 */ public class WExcel { /** * Excel表格 */ private XSSFWorkbook workbook; /** * 表头样式 */ private CellStyle headCellStyle; /** * 错误单元格的样式 */ private CellStyle errorCellStyle; /** * 错误的数字单元格的样式(数字靠右) */ private CellStyle errorNumberCellStyle; /** * 普通单元格的样式 */ private CellStyle normalCellStyle; /** * 普通数字单元格的样式 */ private CellStyle normalNumberCellStyle; /** * 检查消息单元格的样式(最右边一列) */ private CellStyle checkMessageCellStyle; /** * 检查结果失败的单元格的样式 */ private CellStyle checkFailureCellStyle; /** * 检查结果通过的单元格的样式 */ private CellStyle checkSuccessCellStyle; /** * 正常的文字 */ private Font normalFont; /** * 红色文字 */ private Font redFont; /** * 初始化一个Excel文件. */ public void init() { workbook = new XSSFWorkbook(); //---------- 创建样式 ------------------ headCellStyle = new HeadCellStyle(workbook).getStyle(); errorCellStyle = new ErrorCellStyle(workbook).getStyle(); errorNumberCellStyle = new ErrorNumberCellStyle(workbook).getStyle(); normalCellStyle = new NormalCellStyle(workbook).getStyle(); normalNumberCellStyle = new NormalNumberCellStyle(workbook).getStyle(); checkMessageCellStyle = new CheckMessageCellStyle(workbook).getStyle(); checkFailureCellStyle = new CheckFailureCellStyle(workbook).getStyle(); checkSuccessCellStyle = new CheckSuccessCellStyle(workbook).getStyle(); //----------- 创建字体 ---------------- normalFont = new NormalFont(workbook).getFont(); redFont = new RedFont(workbook).getFont(); } /** * 默认无参构造方法. */ public WExcel() { init(); } /** * 将一个DataTable转换为Excel对象,不显示检查结果和错误消息栏.
* 通常用于导出报表. * {@link WExcel#WExcel(boolean flag, WSheet... dataTable)} * * @param tables 要导出的DataTable集合 */ public WExcel(WSheet... tables) { workbook = this.initExcel(false, tables); } /** * 将若干DataTable转换为Excel对象. * * @param flag 是否需要添加检查结果和错误消息栏(true,会添加;false,不会添加) * @param tables DataTable列表 */ public WExcel(boolean flag, WSheet... tables) { workbook = this.initExcel(flag, tables); } public XSSFWorkbook initExcel(boolean flag, WSheet... tables) { init(); Set nameSet = new HashSet<>(tables.length); for (WSheet table : tables) { String name = table.getName(); int index = 1; while (nameSet.contains(name)) { name = table.getName() + "(" + index + ")"; index++; } nameSet.add(name); //创建一个Sheet表 XSSFSheet sheet = workbook.createSheet(name); sheet.setDefaultRowHeightInPoints(20); Row firstRow = sheet.createRow(0); // 下标为0的行开始 XSSFDrawing drawing = sheet.createDrawingPatriarch(); //----------------表头-------------------- if (flag) { // 检查结果栏 org.apache.poi.ss.usermodel.Cell firstCell = firstRow.createCell(0); String columnName = WSheet.CHECK_STATUS_NAME; firstCell.setCellStyle(headCellStyle); firstCell.setCellValue(new XSSFRichTextString(columnName)); sheet.setColumnWidth(0, (4 + 8) * 256); } // 数据栏 int hiddenNumber = 0; for (int j = 0; j < table.getColumnIndex(); j++) { WColumn WColumn = table.getWColumns()[j]; if (WColumn.isHidden()) { hiddenNumber++; continue; } int k = j - hiddenNumber; if (flag) { k++; } org.apache.poi.ss.usermodel.Cell firstCell = firstRow.createCell(k); String columnName = WColumn.getName(); XSSFRichTextString textString; if (WColumn.isRequired()) { textString = new XSSFRichTextString("*" + columnName); textString.applyFont(0, 1, redFont); textString.applyFont(1, textString.length(), normalFont); } else { textString = new XSSFRichTextString(columnName); textString.applyFont(normalFont); } StringBuilder sb = new StringBuilder(); sb.append(WColumn.getDescription()).append("\n"); if (WColumn.getDataType() != DataType.STRING) { // 如果数据类型不是字符串类型,添加特殊数据类型的说明信息。 Field[] fields = DataType.class.getDeclaredFields(); for (Field field : fields) { if (field.getName().equals(WColumn.getDataType().name())) { if (field.isAnnotationPresent(ColumnDescription.class)) { // 获取声明字段上的Description信息。 ColumnDescription columnDescription = field.getAnnotation(ColumnDescription.class); if (columnDescription.value() != null) { sb.append(columnDescription.value()); } } } } } // 如果填写了注释信息 if (sb.length() > 1) { XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) 3, 3, (short) 5, 6); XSSFComment comment = drawing.createCellComment(anchor); comment.setString(sb.toString()); firstCell.setCellComment(comment); } firstCell.setCellValue(textString); firstCell.setCellStyle(headCellStyle); sheet.setColumnWidth(k, (4 + WColumn.getCellWidth()) * 256); } // 错误消息栏 if (flag) { org.apache.poi.ss.usermodel.Cell firstCell = firstRow.createCell(table.getColumnIndex() + 1 - hiddenNumber); String columnName = WSheet.CHECK_STATUS_RESULT; firstCell.setCellStyle(headCellStyle); firstCell.setCellValue(new XSSFRichTextString(columnName)); sheet.setColumnWidth(table.getColumnIndex() + 1, (4 + 10) * 256); } // 冻结第一行 //sheet.createFreezePane(255,1); //------------------数据-------------------- for (int i = 0; i < table.getRowIndex(); i++) { Row row = sheet.createRow(i + 1); boolean rowFlag = true; //如果该行有错误 if (flag) { org.apache.poi.ss.usermodel.Cell xssfCell = row.createCell(0); if (table.getRowError(i) != null) { rowFlag = false; xssfCell.setCellValue("不通过"); xssfCell.setCellStyle(checkFailureCellStyle); } else { xssfCell.setCellValue("通过"); xssfCell.setCellStyle(checkSuccessCellStyle); } } int j = 0; hiddenNumber = 0; for (; j < table.getColumnIndex(); j++) { WColumn WColumn = table.getWColumns()[j]; if (WColumn.isHidden()) { hiddenNumber++; continue; } int k = j - hiddenNumber; if (flag) { k++; } org.apache.poi.ss.usermodel.Cell xssfCell = row.createCell(k); WCell WCell = table.getCell(i, j); if (null == WCell) { continue; } String value = WCell.getValue(); xssfCell.setCellValue(value); // 如果该列是数字类型,则靠右 if (table.getWColumns()[j].getDataType() == DataType.DECIMAL || table.getWColumns()[j].getDataType() == DataType.NUMBER) { if (flag && !WCell.getStatus().equals(Status.PASS)) { xssfCell.setCellStyle(errorNumberCellStyle); } else { xssfCell.setCellStyle(normalNumberCellStyle); } } else { if (flag && !WCell.getStatus().equals(Status.PASS)) { xssfCell.setCellStyle(errorCellStyle); } else { xssfCell.setCellStyle(normalCellStyle); } } } if (flag && !rowFlag) { org.apache.poi.ss.usermodel.Cell xssfCell = row.createCell(j + 1 - hiddenNumber); xssfCell.setCellValue(table.getRowError(i)); xssfCell.setCellStyle(checkMessageCellStyle); } } } return workbook; } /** * 得到已生成好的Excel文件的字节流信息 * * @return 字节流信息 * @throws IOException */ public byte[] getBytes() throws IOException { if (workbook != null) { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); workbook.write(outputStream); return outputStream.toByteArray(); } return null; } //------------ getter & setter -------------------- public Workbook getWorkbook() { return workbook; } public void setWorkbook(XSSFWorkbook workbook) { this.workbook = workbook; } }