因工作需要,把上百个excel文件合并成一个excel文件。
失败方案一:一个输入流 + 一个输出流,循环读取源文件然后直接写入目标文件。
这种方案有个问题,流是无记忆的。同一个输入流,读取一个指针自动后移一位,但是不同的输入流,完全不知道上个流在做什么。最后的结果就是,目标文件的内容和循环中的最后一个源文件的内容相同....
方案二:为了让写入Excel的内容是接着上一次的位置继续写入的,选择使用HSSFWorkbook。
实现的思路是:在页面里,用户填写源文件地址、目标文件地址和目标文件名,提交后,后台先建立一个Excel目标文件,并且把目标文件和源文件都包装成HSSFWorkbook,然后迭代读取源文件的每个cell并将值存入到目标文件HSSFWorkbook对象中,最终数据写入到目标文件中。这样用户可以在填写的目标目标中找到合并文件。
不过在用HSSFWorkbook包装新创建的.xlsx目标文件时遇到了一个小问题:Unable to read entire header; 0 bytes read; expected 512 bytes,就是说包装对象没有没有表头。
问题语句:File file=File.createTempFile(targetPath+File.separator+fileName);
FileInputStream fis = new FileInputStream(file);
HSSFWorkbook targetWork = new HSSFWorkbook(fis);//出问题语句
所以直接创建的.xlsx是不能用HSSFWorkbook包装的,这种办法也不行。
方案三:在页面里,用户只填写源文件地址,提交后文件直接下载。后台不用再创建目标文件,直接把目标HSSFWorkbook对象写入到response流中。代码如下
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
public void excelMerge(HttpServletResponse response, String sourcePath) throws Exception {
// 创建HSSFWorkbook,暂时存放数据
HSSFWorkbook targetWork = new HSSFWorkbook();
HSSFSheet targetSheet = targetWork.createSheet("中石化预分配记录");
targetSheet.setDefaultColumnWidth(20);
targetSheet.setDefaultRowHeightInPoints(20);
// 记录targetWork新建行位置
int targetLineIndex = 0;
// 获取样式集合
Mapstyles = createStyles(targetWork);
//设置标题行
Row titleRow = targetSheet.createRow(targetLineIndex++);
titleRow.setHeightInPoints(30);
Cell titleCell = titleRow.createCell(0);
titleCell.setCellStyle(styles.get("header"));
titleCell.setCellValue("合并文件" + CreateOrderID.getOrderNo());
targetSheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(), titleRow.getRowNum(), titleRow.getRowNum(), 4));
// 设置表头行
Row headerRow = targetSheet.createRow(targetLineIndex++);
headerRow.setHeightInPoints(16);
ListheaderList = new ArrayList<>();
headerList.add("卡号");
headerList.add("时间");
headerList.add("金额");
headerList.add("余额");
headerList.add("地址");
for (int i = 0; i < headerList.size(); i++) {
Cell cell = headerRow.createCell(i);
cell.setCellStyle(styles.get("title"));
cell.setCellValue(headerList.get(i));
targetSheet.autoSizeColumn(i);
}
for (int i = 0; i < headerList.size(); i++) {
int colWidth = targetSheet.getColumnWidth(i) * 5;
targetSheet.setColumnWidth(i, colWidth < 3000 ? 3000 : colWidth);
}
HSSFWorkbook workbook;
HSSFSheet sheet;
File sourcePathFile = new File(sourcePath);
for (File file : sourcePathFile.listFiles()) {
if (file.isFile() && file.getName().endsWith(".xlsx")) {
workbook = new HSSFWorkbook(new FileInputStream(file));
sheet = workbook.getSheetAt(0);
for (int i = 2; i < sheet.getLastRowNum(); i++) {
Row sourceRow = sheet.getRow(i);
Row targetRow = targetSheet.createRow(targetLineIndex++);
for (int j = 0; j < sourceRow.getLastCellNum(); j++) {//Cell
Cell cell = sourceRow.getCell(j);
switch (cell.getCellType()) {
case Cell.CELL_TYPE_BLANK:
break;
case Cell.CELL_TYPE_STRING:
System.out.println();
targetRow.createCell(j).setCellValue(cell.getStringCellValue());
break;
case Cell.CELL_TYPE_NUMERIC:
targetRow.createCell(j).setCellValue(cell.getNumericCellValue());
break;
default:
targetRow.createCell(j).setCellValue(cell.toString());
}
}
}
}
}
response.reset();
response.setContentType("application/octet-stream; charset=utf-8");
response.setHeader("Content-Disposition", "attachment; filename=" + Encodes.urlEncode("合并文件" + CreateOrderID.getOrderNo() + ".xlsx"));
targetWork.write(response.getOutputStream());
}
// 工具方法,设置Excel表样式
private MapcreateStyles(Workbook wb) {
Mapstyles = new HashMap<>();
CellStyle style = wb.createCellStyle();
style.setAlignment(CellStyle.ALIGN_CENTER);
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
Font titleFont = wb.createFont();
titleFont.setFontName("Arial");
titleFont.setFontHeightInPoints((short) 12);
titleFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
style.setFont(titleFont);
styles.put("title", style);
style = wb.createCellStyle();
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
style.setBorderRight(CellStyle.BORDER_THIN);
style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setBorderLeft(CellStyle.BORDER_THIN);
style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setBorderTop(CellStyle.BORDER_THIN);
style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setBorderBottom(CellStyle.BORDER_THIN);
style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
Font dataFont = wb.createFont();
dataFont.setFontName("Arial");
dataFont.setFontHeightInPoints((short) 10);
style.setFont(dataFont);
styles.put("data", style);
style = wb.createCellStyle();
style.setAlignment(CellStyle.ALIGN_LEFT);
style.cloneStyleFrom(styles.get("data"));
styles.put("data1", style);
style = wb.createCellStyle();
style.cloneStyleFrom(styles.get("data"));
style.setAlignment(CellStyle.ALIGN_CENTER);
styles.put("data2", style);
style = wb.createCellStyle();
style.cloneStyleFrom(styles.get("data"));
style.setAlignment(CellStyle.ALIGN_RIGHT);
styles.put("data3", style);
style = wb.createCellStyle();
style.cloneStyleFrom(styles.get("data"));
// style.setWrapText(true);
style.setAlignment(CellStyle.ALIGN_CENTER);
style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setFillPattern(CellStyle.SOLID_FOREGROUND);
Font headerFont = wb.createFont();
headerFont.setFontName("Arial");
headerFont.setFontHeightInPoints((short) 16);
headerFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
headerFont.setColor(IndexedColors.WHITE.getIndex());
style.setFont(headerFont);
styles.put("header", style);
return styles;
}