`
zhuyufufu
  • 浏览: 139593 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Java POI Excel sheet 合并遇到的问题解决2

阅读更多
上接 Java POI Excel sheet 合并
http://zhuyufufu.iteye.com/blog/2033386
Java POI Excel sheet 合并问题解决
http://zhuyufufu.iteye.com/blog/2035033

上面的博文生成的拷贝Excel程序在Cell非常多的时候还会出问题

   Caused by: java.lang.IllegalStateException: The maximum number of cell styles was exceeded. You can define up to 4000 styles in a .xls workbook

   解决的办法就是,每一种cell样式存储起来,共用。
  
   从中也可以看出来office Excel在实现样式的时候做了很多限制。

上具体的代码

public static HSSFWorkbook mergeHSSFWorkbooks(HSSFWorkbook[] workbooks) {
		if(workbooks == null || workbooks.length == 0){
			return null;
		}else if(workbooks.length == 1){
			return workbooks[0];
		}
		HSSFWorkbook wbFirst = workbooks[0];
		HSSFSheet toSheet = wbFirst.getSheetAt(0);
		for (int i = 1; i < workbooks.length; i++) {
			HSSFWorkbook wb = workbooks[i];
			HSSFSheet fromsheet = wb.getSheetAt(0);
			if(i == 1){
				copyRows(wbFirst, wb, fromsheet, toSheet, fromsheet.getFirstRowNum(), fromsheet.getLastRowNum(), (toSheet.getLastRowNum()));
			}else{
				copyRows(wbFirst, wb, fromsheet, toSheet, fromsheet.getFirstRowNum(), fromsheet.getLastRowNum(), (toSheet.getLastRowNum() + 1));
			}
		}
		return wbFirst;
	}
	
	/**
	 * @param destWorkBook 目标workbook
	 * @param sourceWorkBook 源workbook
	 * @param sourceSheet 源sheet
	 * @param targetSheet 目sheet
	 * @param pStartRow 起始读取行
	 * @param pEndRow 结束读取行
	 * @param pPosition 目标保存
	 */
	public static void copyRows(HSSFWorkbook destWorkBook, HSSFWorkbook sourceWorkBook, HSSFSheet sourceSheet,HSSFSheet targetSheet, int pStartRow, int pEndRow, int pPosition) {
		HSSFRow sourceRow = null;
		HSSFRow targetRow = null;
		HSSFCell sourceCell = null;
		HSSFCell targetCell = null;
		int cType;
		int i;
		int j;
		int targetRowFrom;
		int targetRowTo;

		if ((pStartRow == -1) || (pEndRow == -1)) {
			return;
		}

		List<CellRangeAddress> oldRanges = new ArrayList<CellRangeAddress>();
		for (i = 0; i < sourceSheet.getNumMergedRegions(); i++) {
			oldRanges.add(sourceSheet.getMergedRegion(i));
		}

		// 拷贝合并的单元格。原理:复制当前合并单元格后,原位置的格式会移动到新位置,需在原位置生成旧格式
		for (int k = 0; k < oldRanges.size(); k++) {
			CellRangeAddress oldRange = oldRanges.get(k);
			CellRangeAddress newRange = new CellRangeAddress(oldRange
					.getFirstRow(), oldRange.getLastRow(), oldRange
					.getFirstColumn(), oldRange.getLastColumn());

			if (oldRange.getFirstRow() >= pStartRow
					&& oldRange.getLastRow() <= pEndRow) {
				targetRowFrom = oldRange.getFirstRow() - pStartRow + pPosition;
				targetRowTo = oldRange.getLastRow() - pStartRow + pPosition;
				oldRange.setFirstRow(targetRowFrom);
				oldRange.setLastRow(targetRowTo);
				targetSheet.addMergedRegion(oldRange);
				sourceSheet.addMergedRegion(newRange);
			}
		}
		// 设置列宽
		for (i = pStartRow; i <= pEndRow; i++) {
			sourceRow = sourceSheet.getRow(i);
			if (sourceRow != null) {
				for (j = sourceRow.getLastCellNum(); j > sourceRow.getFirstCellNum(); j--) {
					targetSheet.setColumnWidth(j, sourceSheet.getColumnWidth(j));
					targetSheet.setColumnHidden(j, false);
				}
				break;
			}
		}
		List<HSSFCellStyle> cellStyleList = new ArrayList<HSSFCellStyle>();
		// 拷贝行并填充数据
		for (; i <= pEndRow; i++) {
			sourceRow = sourceSheet.getRow(i);
			if (sourceRow == null) {
				continue;
			}
			targetRow = targetSheet.createRow(i - pStartRow + pPosition);
			targetRow.setHeight(sourceRow.getHeight());
			for (j = sourceRow.getFirstCellNum(); j <= sourceRow.getPhysicalNumberOfCells(); j++) {
				sourceCell = sourceRow.getCell(j);
				if (sourceCell == null) {
					continue;
				}
				targetCell = targetRow.createCell(j);
				//复制样式
				//样式的设置
				HSSFCellStyle cStyle = compareStoreAndGetCellStyle(cellStyleList, sourceCell.getCellStyle(), destWorkBook, sourceWorkBook);
				targetCell.setCellStyle(cStyle);

				cType = sourceCell.getCellType();
				targetCell.setCellType(cType);
				switch (cType) {
				case HSSFCell.CELL_TYPE_BOOLEAN:
					targetCell.setCellValue(sourceCell.getBooleanCellValue());
					// System.out.println("--------TYPE_BOOLEAN:" + targetCell.getBooleanCellValue());
					break;
				case HSSFCell.CELL_TYPE_ERROR:
					targetCell.setCellErrorValue(sourceCell.getErrorCellValue());
					// System.out.println("--------TYPE_ERROR:" + targetCell.getErrorCellValue());
					break;
				case HSSFCell.CELL_TYPE_FORMULA:
					// parseFormula这个函数的用途在后面说明
					targetCell.setCellFormula(parseFormula(sourceCell.getCellFormula()));
					// System.out.println("--------TYPE_FORMULA:" + targetCell.getCellFormula());
					break;
				case HSSFCell.CELL_TYPE_NUMERIC:
					targetCell.setCellValue(sourceCell.getNumericCellValue());
					// System.out.println("--------TYPE_NUMERIC:" + targetCell.getNumericCellValue());
					break;
				case HSSFCell.CELL_TYPE_STRING:
					targetCell.setCellValue(sourceCell.getRichStringCellValue());
					// System.out.println("--------TYPE_STRING:" + i + targetCell.getRichStringCellValue());
					break;
				default:
					targetCell.setCellValue(sourceCell.getRichStringCellValue());
					// System.out.println("--------TYPE_STRING:" + i + targetCell.getRichStringCellValue());
					break;
				}
			}
		}
	}
	

	/**
	 * 比较存储并获得cellstyle
	 * @param cellStyleList
	 * @param cellStyle
	 * @param sourceWorkBook
	 * @return
	 */
	private static HSSFCellStyle compareStoreAndGetCellStyle(
			List<HSSFCellStyle> cellStyleList, 
			HSSFCellStyle sourceCellStyle,
			HSSFWorkbook destWorkBook,
			HSSFWorkbook sourceWorkBook) {
		for (int index = 0; index < cellStyleList.size(); index++) {
			HSSFCellStyle cellStyle = cellStyleList.get(index);
			if(isEqual(cellStyle, sourceCellStyle, destWorkBook, sourceWorkBook)){
				return cellStyle;
			}
		}
		//拷贝新的样式到列表
		HSSFCellStyle cStyle = destWorkBook.createCellStyle();
		cStyle = copyCellStyle(cStyle, sourceCellStyle, sourceWorkBook);
		cellStyleList.add(cStyle);
		return cStyle;
	}

	/**
	 * 两个cellStyle是否相同
	 * @param cellStyle
	 * @param sourceCellStyle
	 * @param sourceWorkBook 
	 * @param destWorkBook 
	 * @return
	 */
	private static boolean isEqual(HSSFCellStyle cellStyle,
			HSSFCellStyle sourceCellStyle, HSSFWorkbook destWorkBook, HSSFWorkbook sourceWorkBook) {
		//判断换行样式是否一样
		if(cellStyle.getWrapText() != sourceCellStyle.getWrapText()){
			return false;
		}
		//对齐方式是否一样
		if(cellStyle.getAlignment() != sourceCellStyle.getAlignment()){
			return false;
		}
		if(cellStyle.getVerticalAlignment()!= sourceCellStyle.getVerticalAlignment()){
			return false;
		}
		//边框是否一样
		if(cellStyle.getBorderBottom()!= sourceCellStyle.getBorderBottom()){
			return false;
		}
		if(cellStyle.getBorderLeft()!= sourceCellStyle.getBorderLeft()){
			return false;
		}
		if(cellStyle.getBorderRight()!= sourceCellStyle.getBorderRight()){
			return false;
		}
		if(cellStyle.getBorderTop()!= sourceCellStyle.getBorderTop()){
			return false;
		}
		if(cellStyle.getBottomBorderColor()!= sourceCellStyle.getBottomBorderColor()){
			return false;
		}
		if(cellStyle.getLeftBorderColor()!= sourceCellStyle.getLeftBorderColor()){
			return false;
		}
		if(cellStyle.getRightBorderColor()!= sourceCellStyle.getRightBorderColor()){
			return false;
		}
		if(cellStyle.getTopBorderColor()!= sourceCellStyle.getTopBorderColor()){
			return false;
		}
		//字体是否一样
		HSSFFont sourceFont = sourceCellStyle.getFont(sourceWorkBook);
		HSSFFont destFont = cellStyle.getFont(destWorkBook);
		if(destFont.getBoldweight() != sourceFont.getBoldweight()){
			return false;
		}
		if(destFont.getCharSet() != sourceFont.getCharSet()){
			return false;
		}
		if(destFont.getColor() != sourceFont.getColor()){
			return false;
		}
		if(destFont.getColor() != sourceFont.getColor()){
			return false;
		}
		if(destFont.getFontHeight() != sourceFont.getFontHeight()){
			return false;
		}
		if(destFont.getFontHeightInPoints() != sourceFont.getFontHeightInPoints()){
			return false;
		}
		if(destFont.getIndex() != sourceFont.getIndex()){
			return false;
		}
		if(destFont.getItalic() != sourceFont.getItalic()){
			return false;
		}
		if(destFont.getUnderline() != sourceFont.getUnderline()){
			return false;
		}
		if(destFont.getStrikeout() != sourceFont.getStrikeout()){
			return false;
		}
		if(!destFont.getFontName().equals(sourceFont.getFontName())){
			return false;
		}
		//别的样式是否一样
		return true;
	}

	/**
	 * 样式拷贝
	 * @param cStyle 目标style
	 * @param sourceCellStyle 源style
	 * @param sourceWorkBook 源workBook
	 * @return
	 */
	private static HSSFCellStyle copyCellStyle(HSSFCellStyle cStyle, HSSFCellStyle sourceCellStyle, HSSFWorkbook sourceWorkBook) {
		if(sourceCellStyle == null || cStyle == null){
			return cStyle;
		}
		//是否换行
		cStyle.setWrapText(sourceCellStyle.getWrapText());
		//字体拷贝
		cStyle.setFont(sourceCellStyle.getFont(sourceWorkBook));
//		 cStyle.cloneStyleFrom(sourceCellStyle);
		//拷贝对齐方式
		cStyle.setAlignment(sourceCellStyle.getAlignment());
		cStyle.setVerticalAlignment(sourceCellStyle.getVerticalAlignment());
		//边框拷贝
		cStyle.setBorderBottom(sourceCellStyle.getBorderBottom());
		cStyle.setBorderLeft(sourceCellStyle.getBorderLeft());
		cStyle.setBorderRight(sourceCellStyle.getBorderRight());
		cStyle.setBorderTop(sourceCellStyle.getBorderTop());
		cStyle.setBottomBorderColor(sourceCellStyle.getBottomBorderColor());
		cStyle.setLeftBorderColor(sourceCellStyle.getLeftBorderColor());
		cStyle.setRightBorderColor(sourceCellStyle.getRightBorderColor());
		cStyle.setTopBorderColor(sourceCellStyle.getTopBorderColor());
		//别的样式的拷贝
		return cStyle;
	}

	/**
	 * 处理公式
	 * @param pPOIFormula
	 * @return
	 */
	private static String parseFormula(String pPOIFormula) {
		final String cstReplaceString = "ATTR(semiVolatile)"; //$NON-NLS-1$
		StringBuffer result = null;
		int index;
		result = new StringBuffer();
		index = pPOIFormula.indexOf(cstReplaceString);
		if (index >= 0) {
			result.append(pPOIFormula.substring(0, index));
			result.append(pPOIFormula.substring(index + cstReplaceString.length()));
		} else {
			result.append(pPOIFormula);
		}
		return result.toString();
	}


0
1
分享到:
评论

相关推荐

    poi实现多sheet合并

    在IT行业中,尤其是在数据分析、报表处理等领域,经常需要对Excel...通过以上步骤,你可以实现将多个Excel文件的多个Sheet合并到一个新文件中,每个Sheet对应源文件的一个Sheet,满足了“poi实现多sheet合并”的需求。

    java excel poi合并单元格

    在Java编程中,Apache POI库是一个非常流行的用于读写Microsoft Office格式文件的库,包括Excel。本篇文章将深入探讨如何使用Apache POI来合并Excel工作表中的单元格,以实现标题或者表头的美化。 首先,理解Excel...

    Poi 读写Excel 合并ExcelSheet Struts2实现

    总的来说,通过Apache POI与Struts2的结合,我们可以轻松地在Java Web应用中实现Excel文件的读写和合并操作。这在数据分析、报表生成、数据导入导出等场景下非常实用。但要注意处理大数据时性能问题,因为内存中存储...

    POI读取Excel合并单元格并储存

    本文将深入探讨如何使用Java的Apache POI库来读取Excel文件,并处理其中合并单元格的数据,同时将这些数据存储到实体类中以供后续使用。 Apache POI是一个强大的库,允许程序员使用Java来创建、修改和显示Microsoft...

    使用poi方式导出excel(分多个sheet导出)

    在Java开发中,Apache POI 是一个非常流行的库,它允许程序员创建、修改和显示Microsoft Office格式的文件,包括Excel。本教程将详细介绍如何利用Apache POI库来实现使用多个Sheet(工作簿)导出一个Excel文件的功能...

    利用POI合并多个Excel表

    在IT领域,Apache POI是一个广泛使用的Java库,它允许开发者读取、写入和修改Microsoft Office格式的文件,特别是Excel工作簿。本教程将深入探讨如何利用Apache POI库来合并多个Excel工作表,这对于处理大量数据或者...

    poi获取合并单元格

    在本篇文章中,我们将详细介绍如何使用 POI 处理 Excel 文件中的合并单元格。 #### 二、关键概念与术语解释 1. **合并单元格**:在 Excel 中,可以通过选择相邻的多个单元格并将其合并为一个单元格来简化数据展示...

    POI合并多个相同的Excel或者合并Word文件

    总的来说,Java的POI库为我们提供了处理Microsoft Office文件的强大工具,无论是合并Excel还是Word文档,都能有效地完成任务。通过熟练掌握POI的使用,可以极大地提升工作效率,简化数据管理和文档处理的工作流程。

    poi获取exccel有合并单元格的数据

    ### 使用Apache POI获取含有合并单元格的Excel数据并存储为List 在处理Excel文档时,经常需要读取其中的数据并进行进一步的操作。当Excel文件中含有合并单元格时,简单的读取方法可能无法准确地获取到所有数据。...

    poi excel 模板读取 复制表 复制行且区分合并行

    本篇将详细介绍如何使用Apache POI来读取Excel模板,复制工作表(Sheet)以及复制行,并特别关注如何处理合并单元格的情况。 首先,我们需要引入Apache POI的相关依赖库到我们的项目中。在Maven项目中,可以在pom....

    POI导出Excel工具类,自动设置标题 列名 文件名,可插入图片,合并单元格

    Apache POI是一个强大的Java库,专门用于处理Microsoft Office格式的文件,尤其是Excel。在这个场景中,我们关注的是如何使用POI来创建一个功能丰富的Excel导出工具类,它能够自动设置标题、列名、文件名,并且支持...

    java poi操作excel小例子

    Java POI 操作 Excel 是一个常见的任务,在许多业务场景中都需要用到,比如数据导入导出、数据分析等。Apache POI 是一个流行的开源库,它允许开发者使用 Java 来读写 Microsoft Office 格式的文件,其中包括 Excel ...

    java使用poi在excel单元格添加超链接,设置字体颜色(csdn)————程序.pdf

    在Java开发中,Apache POI库是一个非常实用的工具,用于读取、写入和修改Microsoft Office格式的文件,特别是Excel。本篇文章主要探讨如何利用POI在Excel单元格中添加超链接,并设置字体颜色。 首先,为了使用...

    JAVA POI导出EXCEL代码

    Java POI库是Apache软件基金会的一个项目,专门用于读写Microsoft Office格式的文件,包括Excel。在Java开发中,我们经常使用POI库来处理Excel数据,如读取、写入和修改Excel文件。本篇文章将详细介绍如何使用JAVA ...

    java poi处理excel数据

    首先,`问题.docx`可能是你在使用POI过程中遇到的问题汇总,它可能包含了错误信息、解决步骤或常见问题的解决方案。通过阅读这份文档,你可以避免或解决类似的问题,提升开发效率。 其次,`统计年鉴示例.xlsx`是一...

    java利用poi对Excel进行读写操作支持多sheet格式

    总之,Java POI库为开发者提供了强大而灵活的工具,使得在Java程序中处理Excel文件变得简单易行,无论是一份包含单Sheet的简单报表,还是带有复杂结构和逻辑的多Sheet文件,都能轻松应对。通过深入学习和实践,你...

    poi生成Excel及合并单元格示例

    在本示例中,我们将重点讨论如何使用 Apache POI 来生成 Excel 文件,并进行单元格的合并操作。 首先,我们需要引入 Apache POI 的相关依赖库。如果你使用的是 Maven,可以在项目的 `pom.xml` 文件中添加以下依赖:...

    java poi 操作Excel

    Java POI 是一个开源项目,专门用于处理Microsoft Office格式的文件,包括Excel、Word和PowerPoint等。在Java世界中,如果你想对Excel进行读写操作,POI库是不可或缺的工具。下面将详细介绍如何使用Java POI来操作...

    Java POI 生成Excel(xlsx)文件

    Java POI 是一个开源项目,专门用于处理Microsoft Office格式的文件,包括Excel、Word和PowerPoint等。在Java中,如果你需要生成或操作Excel文件,尤其是.xlsx格式(这是Excel 2007及以上版本使用的Open XML格式),...

    java POI读取excel文件数据

    在这个场景中,我们将详细探讨如何使用Java POI读取Excel文件中的数据,包括获取总行数、列数、单元格内容、合并单元格、行高、列宽以及图片等信息。 首先,确保在项目中已经引入了Apache POI的依赖库。如果你使用...

Global site tag (gtag.js) - Google Analytics