读书人

将多个Excel资料合并成一个的源码

发布时间: 2012-09-14 11:53:44 作者: rapoo

将多个Excel文件合并成一个的源码

源码是在poi-3.1-FINAL-20080629版本下编译通过。

?

本源码修正了获取sheet中数据行数的BUG,详情看getRows方法。

public class ExcelMergeUtil {  public static void merge(List<String> sourceFiles, String destFile)throws Exception{InputStream[] inputs = new InputStream[sourceFiles.size()];     for(int i=0; i<sourceFiles.size(); i++) {         inputs[i] = new FileInputStream(sourceFiles.get(i));       }           OutputStream out = new FileOutputStream(destFile);         merge(inputs, out);}public static void merge(InputStream[] inputs, OutputStream out)throws Exception{  Map map = null;try{if(inputs == null || inputs.length <= 1) {   throw new IllegalArgumentException("没有传入输入流数组或只有一个输入流!");   }   System.out.println("需要合并的文件数为:" + inputs.length);//第一个文档List<Record> rootRecords = getRecords(inputs[0]); Workbook workbook = Workbook.createWorkbook(rootRecords); List<Sheet> sheets = getSheets(workbook, rootRecords);   if(sheets == null || sheets.size() == 0) {   throw new IllegalArgumentException("第一个文档格式错误,必须至少有一个sheet!");   }   //以第一个文档的最后一个sheet为根,以后的数据都追加在这个sheet后面   Sheet rootSheet = sheets.get(sheets.size() - 1);    int rootRows = getRows(rootRecords); //记录第一篇文档的行数,以后的行数在此基础上增加   rootSheet.setLoc(rootSheet.getDimsLoc());   map = new HashMap(1000);for(int i = 1; i < inputs.length; i++){ //从第二篇开始遍历   List<Record> records = getRecords(inputs[i]);   int rowsOfCurXls = 0;   //遍历当前文档的每一个record   for(Iterator it = records.iterator(); it.hasNext();){           Record record = (Record) it.next();           if(record.getSid() == RowRecord.sid){ //如果是RowRecord           RowRecord rowRecord = (RowRecord) record;           rowRecord.setRowNumber(rootRows + rowRecord.getRowNumber()); //调整行号           rootSheet.addRow(rowRecord); //追加Row           rowsOfCurXls++; //记录当前文档的行数           }           //SST记录,SST保存xls文件中唯一的String,各个String都是对应着SST记录的索引           else if (record.getSid() == SSTRecord.sid){           SSTRecord sstRecord = (SSTRecord) record;           for (int j = 0; j < sstRecord.getNumUniqueStrings(); j++) {           int index = workbook.addSSTString(sstRecord.getString(j));           //记录原来的索引和现在的索引的对应关系           map.put(Integer.valueOf(j), Integer.valueOf(index));           }           }        else if (record.getSid() == LabelSSTRecord.sid){           LabelSSTRecord label = (LabelSSTRecord) record;           //调整SST索引的对应关系           label.setSSTIndex( ((Integer)map.get(Integer.valueOf(label.getSSTIndex()))).intValue() );           }                   //追加ValueCell           if(record instanceof CellValueRecordInterface){           CellValueRecordInterface cell = (CellValueRecordInterface) record;           int cellRow = cell.getRow() + rootRows;           cell.setRow(cellRow);           rootSheet.addValueRecord(cellRow, cell);           }   }         rootRows += rowsOfCurXls;      }       byte[] data = getBytes(workbook, sheets.toArray(new Sheet[0]));          write(out, data);         System.out.println("合并完成");}finally{if(map!=null){map.clear();map = null;}}}     static void write(OutputStream out, byte[] data)throws Exception{   POIFSFileSystem fs = new POIFSFileSystem();     try{   fs.createDocument(new ByteArrayInputStream(data), "Workbook");   fs.writeFilesystem(out);   out.flush();   }finally{   try{   out.close();   }catch(IOException e){   e.printStackTrace();   }   }   }     /** * 获取Sheet列表 */  static List<Sheet> getSheets(Workbook workbook, List<Record> records)throws Exception{     int recOffset = workbook.getNumRecords();     int sheetNum = 0;         convertLabelRecords(records, recOffset, workbook);         List<Sheet> sheets = new ArrayList<Sheet>();     while(recOffset < records.size()){     Sheet sheet = Sheet.createSheet(records, sheetNum++, recOffset);  recOffset = sheet.getEofLoc() + 1;     if(recOffset == 1) break;    sheets.add(sheet);     }       return sheets;     }   /**   * 取得一个sheet中数据的行数   */  static int getRows(List<Record> records) {         int row = 0;         for(Iterator it = records.iterator(); it.hasNext();){           Record record = (Record) it.next();        if(record.getSid() == DimensionsRecord.sid){           DimensionsRecord dr = (DimensionsRecord)record;        row = dr.getLastRow();        break;        }         }         return row;     }         /**   * 获取Excel文档的记录集   */  static List<Record> getRecords(InputStream input) {     try{     POIFSFileSystem poifs = new POIFSFileSystem(input);   InputStream stream = poifs.getRoot().createDocumentInputStream("Workbook");     return RecordFactory.createRecords(stream);  }catch(IOException e){     System.out.println("ExcelMergeUtil.getRecords: " + e.toString());  e.printStackTrace();     }     return Collections.EMPTY_LIST;     }       static void convertLabelRecords(List<Record> records, int offset, Workbook workbook)throws Exception{     for(int k = offset; k < records.size(); k++){     Record rec = (Record) records.get(k);       if (rec.getSid() == LabelRecord.sid) {     LabelRecord oldrec = (LabelRecord) rec;             records.remove(k);             int stringid = workbook.addSSTString(new UnicodeString(oldrec.getValue()));           LabelSSTRecord newrec = new LabelSSTRecord();         newrec.setRow(oldrec.getRow());           newrec.setColumn(oldrec.getColumn());           newrec.setXFIndex(oldrec.getXFIndex());           newrec.setSSTIndex(stringid);           records.add(k, newrec);     }  }     }       static byte[] getBytes(Workbook workbook, Sheet[] sheets) {   int nSheets = sheets.length;          for(int i = 0; i < nSheets; i++){     sheets[i].preSerialize();     }       int totalsize = workbook.getSize();         int[] estimatedSheetSizes = new int[nSheets];     for(int k = 0; k < nSheets; k++){     workbook.setSheetBof(k, totalsize);     int sheetSize = sheets[k].getSize();     estimatedSheetSizes[k] = sheetSize;     totalsize += sheetSize;  }     byte[] retval = new byte[totalsize];     int pos = workbook.serialize(0, retval);       for(int k = 0; k < nSheets; k++){     int serializedSize = sheets[k].serialize(pos, retval);     if(serializedSize != estimatedSheetSizes[k]){     throw new IllegalStateException("Actual serialized sheet size (" + serializedSize     + ") differs from pre-calculated size (" + estimatedSheetSizes[k] + ") for sheet (" + k     + ")");   }     pos += serializedSize;     }       return retval;     }   } 

?

读书人网 >编程

热点推荐