java实现多个excel文件合并成一个excel文件

因工作需要,把上百个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;
      // 获取样式集合
      Map styles = 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);
      List headerList = 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 Map createStyles(Workbook wb) {
      Map styles = 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;
   }

你可能感兴趣的:(java实现多个excel文件合并成一个excel文件)