poi处理excel文件

最近,做了一个项目,其中一个主要的环节就是处理excel文件,之前选择使用jxl处理,后来发现不好,所以选用了poi处理,虽然还有一些不尽人意,但已经很好了。

困难之处:

1.如果选择迭代期处理单元格,可能会把空单元格直接干掉,有可能造成串列,如果你的需求不用理会串列的情况,而只是需要内容,那么无所谓,但是,如果你需要列对应关系不变的话,问题就大了

2.合并单元格拆分,这个拆分还是不太好处理的,你得考虑这个是不是合并单元格,如果是,怎么拆开,因为poi默认不处理的话,只把内容赋给第一个单元格,其他的为空,如果这样的话,就不太人性化

3.单元格存在换行,tab,空格,如果出现这些,怎么处理,而且换行还有两种形式,\n和\r

4.单元格格式问题,我在网上查,有很多种格式,但是我这个程序,只处理了其中几个,并没有全处理,因为网上那些我尝试的时候,发现并不好用,没有办法处理

5.excel文件有03版和07版,怎么兼容

大致问题差不多就这么多,也是网上没啥有用资料可用的问题

项目环境搭建就是使用maven管理工具,引入poi依赖,这个我就不多说了

我对上面问题的解决思路就是:(和上面的问题是一一对应关系,望各位观众老爷多注意)

1.我不是用迭代期来遍历单元格,而是使用传统的遍历方式,for (int aa = 0; aa <= endRow; aa++)这种遍历单元格,这样就可以把所有的单元格取出来,不管他是不是空的

2.先把这个excel文件所有的合并单元格放到一个list中保存,然后开始遍历单元格,每遍历一个单元格判断一下是否属于合并单元格,如果是,把合并单元格内容赋值给当前单元格(这个是必须设置的,不设置,就为空)

3.单元格存在的这些符号,我会把他替换成指定的字符串,以便于后面区分

4.格式问题,这个看代码

5.同上

下面开始我们最关心的环节,也就是上代码环节

a.

public static String getContent01(String filePath) {
		StringBuffer sb = new StringBuffer();
		if (new File(filePath).length() == 0) {
			return null;
		}
		boolean isE2007 = false; // 判断是否是excel2007格式
		if (filePath.endsWith("xlsx")) {
			isE2007 = true;
		}
		try {
			InputStream input = new FileInputStream(filePath); // 建立输入流
			Workbook wb = null;
			int sheets = 0;
			// 根据文件格式(2003或者2007)来初始化
			if (isE2007) {
				wb = new XSSFWorkbook(input);
			} else {
				wb = new HSSFWorkbook(input);
			}
			sheets = wb.getNumberOfSheets();
			for (int a = 0; a < sheets; a++) {
				// 获取Sheet表
				Sheet sheet = wb.getSheetAt(a);
				// 获得合并单元格加入list中
				List<CellRangeAddress> list = getCombineCell(sheet);
				// 首尾两行行数
				int firstRow = sheet.getFirstRowNum();
				int endRow = sheet.getLastRowNum();
				for (int aa = 0; aa <= endRow; aa++) {
					Row row = sheet.getRow(aa);
					if (row != null) {
						int endCell = row.getLastCellNum();
						for (int bb = 0; bb < endCell; bb++) {
							boolean trueOrFalse = false;
							Cell cell = row.getCell(bb);
							boolean flag = false;
							if (cell != null) {
								// 判断是否为合并单元格
								flag = isCombineCell(list, cell, sheet);
							}

							// System.out.println(flag);
							if (flag) {
								// 如果为合并单元格,将设置单元格内容
								trueOrFalse = setCellValue(list, cell, sheet);
							}
							if (cell == null || cell.getCellType() == Cell.CELL_TYPE_BLANK) {
								sb.append("\t");
							} else {
								String cellValue = setCellStyle(cell);
								sb.append(cellValue).append("\t");
							}
						}
					} else {
						continue;
					}
					sb.append("\n");
				}
			}
			return sb.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

b.将所有的合并单元格放到list中

/**
	 * 合并单元格处理--加入list
	 * 
	 * @param sheet
	 * @return
	 */
	public static List<CellRangeAddress> getCombineCell(Sheet sheet) {
		List<CellRangeAddress> list = new ArrayList<>();
		// 获得一个 sheet 中合并单元格的数量
		int sheetmergerCount = sheet.getNumMergedRegions();
		// 遍历合并单元格
		for (int i = 0; i < sheetmergerCount; i++) {
			// 获得合并单元格加入list中
			CellRangeAddress ca = sheet.getMergedRegion(i);
			list.add(ca);
		}
		return list;
	}

c.判断单元格是否为合并单元格

/**
	 * 判断单元格是否为合并单元格
	 * 
	 * @param listCombineCell
	 *            存放合并单元格的list
	 * @param cell
	 *            需要判断的单元格
	 * @param sheet
	 *            sheet
	 * @return
	 */
	public static Boolean isCombineCell(List<CellRangeAddress> listCombineCell, Cell cell, Sheet sheet) {
		int firstC = 0;
		int lastC = 0;
		int firstR = 0;
		int lastR = 0;
		for (CellRangeAddress ca : listCombineCell) {
			// 获得合并单元格的起始行, 结束行, 起始列, 结束列
			firstC = ca.getFirstColumn();
			lastC = ca.getLastColumn();
			firstR = ca.getFirstRow();
			lastR = ca.getLastRow();
			if (cell.getColumnIndex() <= lastC && cell.getColumnIndex() >= firstC) {
				if (cell.getRowIndex() <= lastR && cell.getRowIndex() >= firstR) {
					return true;
				}
			}
		}
		return false;
	}

d.得到合并单元格首行首列的值,并设置给所有合并单元格

/**
	 * 得到合并单元格首行首列的值,并设置给所有合并单元格
	 * 
	 * @param listCombineCell
	 * @param cell
	 * @param sheet
	 * @return
	 */
	public static boolean setCellValue(List<CellRangeAddress> listCombineCell, Cell cell, Sheet sheet) {
		int firstC = 0;
		int lastC = 0;
		int firstR = 0;
		int lastR = 0;
		for (CellRangeAddress ca : listCombineCell) {
			// 获得合并单元格的起始行, 结束行, 起始列, 结束列
			firstC = ca.getFirstColumn();
			lastC = ca.getLastColumn();
			firstR = ca.getFirstRow();
			lastR = ca.getLastRow();
			if (cell.getColumnIndex() <= lastC && cell.getColumnIndex() >= firstC) {
				if (cell.getRowIndex() <= lastR && cell.getRowIndex() >= firstR) {

					Row row = sheet.getRow(firstR);
					Cell cell_ = row.getCell(firstC);

					String cellValue = "";
					if (cell_.getCellType() == Cell.CELL_TYPE_NUMERIC) {
						DecimalFormat df = new DecimalFormat("#");
						cellValue = df.format(cell_.getNumericCellValue());
						cellValue = cellValue.replace(" ", "|").replace("\n", "|").replace("\r", "|").replace("\t",
								"|");
						cellValue = DataImportUtils.qj2bj(cellValue);
					} else {
						cell_.setCellType(HSSFCell.CELL_TYPE_STRING);
						cellValue = cell_.toString().replace(" ", "|").replace("\n", "|").replace("\r", "|")
								.replace("\t", "|");
						cellValue = DataImportUtils.qj2bj(cellValue);
					}
					// 设置存入内容为字符串
					cell.setCellType(HSSFCell.CELL_TYPE_STRING);
					// 向单元格中放入值
					cell.setCellValue(cellValue);
					return true;
				}
			}
		}
		return false;
	}

e.将单元格格式转换

/**
	 * 将单元格格式转换
	 * 
	 * @param cell
	 * @return
	 */
	public static String setCellStyle(Cell cell) {
		String cellValue = "";
		if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
			DecimalFormat df = new DecimalFormat("#");
			cellValue = df.format(cell.getNumericCellValue());
			cellValue = cellValue.replace(" ", "|").replace("\n", "|").replace("\r", "|").replace("\t", "|");
			cellValue = DataImportUtils.qj2bj(cellValue);
		} else {
			cell.setCellType(HSSFCell.CELL_TYPE_STRING);
			String c = cell.toString().replace(" ", "|").replace("\n", "|").replace("\r", "|").replace("\t", "|");
			cellValue = DataImportUtils.qj2bj(c);
		}
		return cellValue;
	}

f.测试一下

public static void method28(){
		String sb = ExcelUtil.getContent01("G:\\xx\\test__.xlsx");
		System.out.println(sb);
	}

 

测试文件大致就是弄一个合并单元格,任意位置,空单元格,空行,单元格内容存在换行等分隔符。

由于我的测试文件内容为敏感内容(我自己的手机号,住址等信息),不方便贴出来,望各位见谅!!

转载于:https://my.oschina.net/u/2954291/blog/1510995

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值