`

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

    博客分类:
  • java
 
阅读更多

源码是在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;   
  	} 
  
} 

 

分享到:
评论

相关推荐

    易语言源码合并多个Excel文件.rar

    这个“易语言源码合并多个Excel文件.rar”压缩包显然包含了用易语言编写的一个程序,其功能是合并多个Excel文件。这涉及到的知识点主要包括易语言的基本语法、文件操作、数据处理以及Excel文件格式的理解。 首先,...

    合并多个Excel文件易语言源码

    本知识点将详细讲解如何使用易语言来实现合并多个Excel文件的功能,这对于数据处理和分析工作来说是十分实用的。 首先,我们需要理解Excel文件的基本结构。Excel文件通常以.XLS或.XLSX格式存储,它们是由一系列的...

    易语言源码易语言合并EXCEL文件.rar

    压缩包中的"易语言合并EXCEL文件"很可能包含一个或多个源代码文件,这些文件详细展示了如何实现上述步骤。通过阅读源码,你可以学习到易语言如何调用API,处理文件I/O,以及如何组织代码结构来实现特定功能。 5. ...

    易语言合并多个Excel文件

    在IT行业中,易语言是一种基于汉字...总之,“易语言合并多个Excel文件”是一个涉及文件操作、数据处理和字符串编码等多个编程概念的任务。通过理解易语言的基本语法和使用相应的命令,开发者可以有效地完成这项工作。

    EXCEL对比合并工具源码

    源代码,因为该工具还有一些问题没有解决,对于某些EXCEL文件读取出现...将多个EXCEL文件合并成一个文件。只支持.XLS扩展名的文件。 程序运行条件,需要安装Adobe AIR,可以到官网下载:http://get.adobe.com/cn/air/

    合并多个Excel文件.zip易语言项目例子源码下载

    本项目"合并多个Excel文件.zip"是一个易语言的源码示例,它提供了将多个Excel文件整合到一个单一文件中的功能。这个功能在数据分析、报告汇总或自动化工作流中非常实用。 首先,我们要理解如何在易语言中处理Excel...

    合并多个Excel文件.zip

    在某些情况下,我们可能需要将多个Excel文件合并为一个,以便于管理和进一步处理。本主题主要关注如何使用易语言编写源码来实现这个功能。 易语言是一种面向对象的、以中文编程的计算机程序设计语言,它旨在降低...

    npoi实现excel中多个表格数据分别合并

    在“npoi实现excel中多个表格数据分别合并”这个主题中,我们将深入探讨如何利用NPOI库来处理Excel文件中的多个工作表(表格)并进行数据的合并操作。这在数据处理、分析和报告生成等场景中非常常见。 首先,我们...

    Excel 合并操作,小工具源码

    首先,Excel的基本合并功能主要包括单元格合并、工作表合并以及多个Excel文件的合并。单元格合并通常用于格式化表格,例如创建标题或居中的内容。在Excel中,可以通过选择要合并的单元格,然后点击“开始”菜单下的...

    用python合并多个excel的数据到一个表格里,Python源码.zip

    在Python编程环境中,合并多个Excel文件到一个单一的表格是一项常见的任务,特别是在数据分析或数据处理过程中。本场景中,我们有一个名为"用python合并多个excel的数据到一个表格里,Python源码.zip"的压缩包,它...

    易语言合并EXCEL文件

    在易语言中处理Excel文件是一项常见的任务,特别是当需要合并多个Excel文件时。本篇文章将详细解析如何使用易语言实现这一功能,以及涉及到的“取字符代码”知识点。 首先,我们需要了解易语言中与Excel文件操作...

    excel vba实现将多个文件内容复制汇总到一个Excel文件中-VBA源码.rar

    标题中的“Excel VBA实现将多个文件内容复制汇总到一个Excel文件中”是一个常见的自动化任务,尤其对于处理大量数据的工作环境。VBA(Visual Basic for Applications)是Microsoft Office套件中内置的一种编程语言,...

    Python合并多个子文件夹下相同名字的excel文件

    将多个子文件夹下的相同名字的excel文件合并成一个excel,可以直接运行。excel见下面链接 https://amaze.blog.csdn.net/article/details/124889377?spm=1001.2014.3001.5502

    C# Excel数据合并源码.zip

    在描述中提到的数据合并,通常是指将多个Excel工作表或者多个Excel文件中的数据整合到一个新的工作表或文件中。这在数据处理和报告生成中非常常见,比如企业需要汇总多个部门的数据来生成月度或季度报告。C#结合NPOI...

    易语言-合并多个Excel文件易语言

    在给定的标题“易语言-合并多个Excel文件易语言”中,我们可以理解这是一个使用易语言编写的程序或代码库,其主要功能是将多个Excel文件整合到一个单一的文件中。这在数据分析、报告汇总或者数据整理等场景中非常...

    python excel表格合并源代码(有界面程序(pyqt5)

    这个项目利用Python的库和PyQt5 GUI工具包来创建一个用户友好的界面,让用户能够方便地合并多个Excel文件。下面我们将深入探讨这个主题涉及的知识点。 首先,我们要了解Python中的两个关键库:`pandas`和`openpyxl`...

    Excel合并连接工具源码

    本文将深入探讨一个基于Java Swing开发的桌面程序——“Excel合并连接工具”,该工具利用Apache POI库实现了对Excel文件的高效操作,旨在解决上述问题。 首先,让我们了解Apache POI。POI是Apache软件基金会的一个...

    一个文件夹下格式相同excel文件汇总源码

    本代码示例聚焦于如何在一个文件夹中对格式相同的多个Excel文件进行汇总操作。这个过程通常涉及到文件遍历、Excel数据的读取和写入等技术。 首先,我们要理解的是文件遍历的概念。在Python中,我们可以使用`os`库来...

    做了一个java小程序 合并多个excel

    NULL 博文链接:https://a6985600.iteye.com/blog/1673991

Global site tag (gtag.js) - Google Analytics