正常导出报表的场景就是从数据库读取数据,然后按照指定的格式生成报表。其中可能涉及到的就是插入/复制行,单元格设置公式计算这些典型应用。下面就按这个需求给出解决方案。思路就是,首先制定一个Excel模板文档,暂命名为TEMPLATE.xls;然后读取该文档,插入/复制一些数据进去,另存为新的报表文件。这样就不需要在写入数据的时候考虑繁琐的表格样式问题了。
读取模板文件
代码如下 | 复制代码 |
POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(TEMPLATE_PATH)); HSSFWorkbook wb = new HSSFWorkbook(fs, true); HSSFSheet sheet = wb.getSheet("Sheet1"); |
复制行
代码如下 | 复制代码 |
public void copyRow(HSSFWorkbook workbook, HSSFSheet worksheet, int sourceRowNum, int destinationRowNum) { // Get the source / new row HSSFRow newRow = worksheet.getRow(destinationRowNum); HSSFRow sourceRow = worksheet.getRow(sourceRowNum); // If the row exist in destination, push down all rows by 1 else create // a new row if (newRow != null) { worksheet.shiftRows(destinationRowNum, worksheet.getLastRowNum(), 1); } else { newRow = worksheet.createRow(destinationRowNum); } // Loop through source columns to add to new row for (int i = 0; i < sourceRow.getLastCellNum(); i++) { // Grab a copy of the old/new cell HSSFCell oldCell = sourceRow.getCell(i); HSSFCell newCell = newRow.createCell(i); // If the old cell is null jump to next cell if (oldCell == null) { newCell = null; continue; } // Copy style from old cell and apply to new cell HSSFCellStyle newCellStyle = workbook.createCellStyle(); newCellStyle.cloneStyleFrom(oldCell.getCellStyle()); newCell.setCellStyle(newCellStyle); // If there is a cell comment, copy if (newCell.getCellComment() != null) { newCell.setCellComment(oldCell.getCellComment()); } // If there is a cell hyperlink, copy if (oldCell.getHyperlink() != null) { newCell.setHyperlink(oldCell.getHyperlink()); } // Set the cell data type newCell.setCellType(oldCell.getCellType()); // Set the cell data value switch (oldCell.getCellType()) { case Cell.CELL_TYPE_BLANK: newCell.setCellValue(oldCell.getStringCellValue()); break; case Cell.CELL_TYPE_BOOLEAN: newCell.setCellValue(oldCell.getBooleanCellValue()); break; case Cell.CELL_TYPE_ERROR: newCell.setCellErrorValue(oldCell.getErrorCellValue()); break; case Cell.CELL_TYPE_FORMULA: newCell.setCellFormula(oldCell.getCellFormula()); break; case Cell.CELL_TYPE_NUMERIC: newCell.setCellValue(oldCell.getNumericCellValue()); break; case Cell.CELL_TYPE_STRING: newCell.setCellValue(oldCell.getRichStringCellValue()); break; } } // If there are are any merged regions in the source row, copy to new row for (int i = 0; i < worksheet.getNumMergedRegions(); i++) { CellRangeAddress cellRangeAddress = worksheet.getMergedRegion(i); if (cellRangeAddress.getFirstRow() == sourceRow.getRowNum()) { CellRangeAddress newCellRangeAddress = new CellRangeAddress(newRow.getRowNum(), (newRow.getRowNum() + (cellRangeAddress.getFirstRow() - cellRangeAddress.getLastRow())), cellRangeAddress.getFirstColumn(), cellRangeAddress.getLastColumn()); worksheet.addMergedRegion(newCellRangeAddress); } } } |
插入行,并设置相同的样式
代码如下 | 复制代码 |
// Insert one row sheet.shiftRows(rowNumber, sheet.getLastRowNum(), 1); HSSFRow source = sheet.getRow(rowNumber - 1); HSSFRow newRow = sheet.createRow(rowNumber); for (int i = source.getFirstCellNum(), columnNo = source.getLastCellNum(); i < columnNo; i++) { HSSFCell sourceCell = source.getCell(i); HSSFCell targetCell = newRow.createCell(i); targetCell.setCellStyle(sourceCell.getCellStyle()); //Get data from DB and set cell value targetCell.setCellValue("Just for test " + i); } |
设置单元格公式的时候,注意不要加=,直接设置公式就可以。
代码如下 | 复制代码 |
//设置单元格公式 sheet.getRow(total).getCell(10).setCellFormula(String.format("SUM(K%s:K%s)", aIndex + 1, total)); sheet.getRow(total).getCell(11).setCellFormula(String.format("100*J%s/K%s", total + 1, total + 1)); //列宽度自适应 sheet.autoSizeColumn(1); |
保存
代码如下 | 复制代码 |
FileOutputStream fileOut = new FileOutputStream(SAVE_PATH); wb.write(fileOut); fileOut.close(); update @ 2011/11/09 |
删除行,行号0-based
代码如下 | 复制代码 |
public void removeRow(HSSFSheet sheet, int rowIndex) { int lastRowNum = sheet.getLastRowNum(); if (rowIndex >= 0 && rowIndex < lastRowNum) { sheet.shiftRows(rowIndex + 1, lastRowNum, -1); } if (rowIndex == lastRowNum) { HSSFRow removingRow = sheet.getRow(rowIndex); if (removingRow != null) { sheet.removeRow(removingRow); } } } |
这里只是列出了一些简单操作
公司用的一个导出Excel表格的类,贴出来和大家共享下
代码如下 | 复制代码 |
import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.regex.Pattern; import com.shxy.exception.FileOperationException; import jxl.Workbook; } |