1.对比任意两张excel表是否有不同行 并输出哪一行那一列不同

2.包含解析合并单元格方法

3.比较主要思路

a.解析excel;

b.遍历第一张表数据所有行

c.遍历第二张表数据所有行

d.遍历第一张第i行所有列

e.判断d是否都存在c中第i行

f.存在继续判断是否存在c中第i+1行,直到最后一行,若都存在,则继续d;若不存,在打印出来

PoiUtils工具类

  1 package com.tpaic.poiexcel;
2
3 import lombok.extern.log4j.Log4j;
4 import org.apache.poi.ss.usermodel.*;
5 import org.apache.poi.ss.util.CellRangeAddress;
6 import org.apache.poi.xssf.usermodel.XSSFCell;
7 import org.apache.poi.xssf.usermodel.XSSFRow;
8 import org.apache.poi.xssf.usermodel.XSSFSheet;
9 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
10
11 import javax.servlet.http.HttpServletRequest;
12 import javax.servlet.http.HttpServletResponse;
13 import java.io.*;
14 import java.util.ArrayList;
15 import java.util.Arrays;
16 import java.util.List;
17 @Log4j
18 public class PoiUtils {
19
20
21 /**
22 * 对比任意类型两张表是否有不同行
23 * @param excel1Path 对比excel路径
24 * @param excel2Path 被对比excel路径
25 */
26 public static void compareExcelAWithExcelB(String excel1Path,String excel2Path){
27 int sheetNum=0;
28 FileInputStream fis1 = null;
29 FileInputStream fis2 = null;
30 try {
31 fis1 = new FileInputStream(excel1Path);
32 fis2 = new FileInputStream(excel2Path);
33 List<Object[]> objects1 = PoiUtils.readExcelToObj(fis1, sheetNum);//解析第一个excel的数据 对比数据
34 List<Object[]> objects2 = PoiUtils.readExcelToObj(fis2, sheetNum);//解析第二个excel的数据 被对比数据
35
36 //遍历第一个excel数据,即取的对比数据的某一行某一列具体值
37
38 Object [] objArr1 = null;//定义一个对象数组,存放每一行数据
39 List<Object> columnsList = null;//定义一个list,用来存放对比数据某一行的所有列
40
41 Object [] objArr2 = null;//定义一个对象数组,存放每一行数据
42 List<Object> rowList = null;//用来存放第二个excel某一行数据
43
44 //遍历行 第一个excel
45 first: for (int i=0;i<objects1.size();i++){
46
47 objArr1 = objects1.get(i);//将excel1的每行数据存到objArr1
48
49 columnsList = Arrays.asList(objArr1);//将每一行对象数组转为list,为了某行某列的值
50
51 //遍历行 第二个excel
52 second: for (int k=0;k<objects2.size();k++){
53
54 //遍历列 第一个excel
55 for (int j=0;j<columnsList.size();j++){
56
57 objArr2 = objects2.get(k);//将excel2的每行数据村到objArr2
58
59 rowList = Arrays.asList(objArr2);//数组转换list,为了比较excel2中的某一行是否存在excel1中的某一行所有列数据
60
61 boolean contains = rowList.contains(columnsList.get(j));//rowList是否包含columnsList(j)
62 if (!contains){
63 if (k==objects2.size()-1){
64 log.info("第"+(i+1)+"行-----"+Arrays.toString(objArr1));
65 }
66 break;
67 }
68 if (j==columnsList.size()-1){
69 break second;
70 }
71
72 }
73
74 }
75
76 }
77 } catch (Exception e) {
78 e.printStackTrace();
79 }finally {
80 try {
81 if (fis1 != null){
82 fis1.close();
83 }
84 } catch (IOException e) {
85 e.printStackTrace();
86 }
87 try {
88 if (fis2 != null){
89 fis2.close();
90 }
91 } catch (IOException e) {
92 e.printStackTrace();
93 }
94 }
95 }
96
97
98 /**
99 * 读取excel数据,调用这方法开始
100 *
101 * @param is
102 * @param indexNum 至少需要多少列数据
103 */
104 public static List<Object[]> readExcelToObj(InputStream is, int indexNum) {
105
106 Workbook wb = null;
107 List<Object[]> objArrList = null;
108 try {
109 objArrList = new ArrayList<>();
110 wb = WorkbookFactory.create(is);
111 int num = wb.getNumberOfSheets();
112 readExcel(wb, 0, 0, 0, objArrList, indexNum);
113 } catch (Exception e) {
114 e.printStackTrace();
115 }
116 return objArrList;
117 }
118
119 /**
120 * 读取excel文件
121 *
122 * @param wb
123 * @param sheetIndex sheet页下标:从0开始
124 * @param startReadLine 开始读取的行:从0开始
125 * @param tailLine 去除最后读取的行
126 */
127 static Long startMills = null;
128 static Long endMills = null;
129
130 public static void readExcel(Workbook wb, int sheetIndex, int startReadLine, int tailLine, List<Object[]> objArrList, int indexNum) {
131 startMills = System.currentTimeMillis();
132 Sheet sheet = wb.getSheetAt(sheetIndex);
133 Row row = null;
134
135 for (int i = startReadLine; i < sheet.getLastRowNum() - tailLine + 1; i++) {
136 row = sheet.getRow(i);
137 int CellNum = row.getLastCellNum();
138 List<Object> objList = new ArrayList<>();
139 for (int j = 0; j < row.getLastCellNum(); j++) {
140 //for(Cell c : row) {
141 Cell c = row.getCell(j);
142 if (c == null) {
143 objList.add("");
144 continue;
145 }
146 Integer isMerge = isMergedRegion(sheet, i, c.getColumnIndex());
147 //判断是否具有合并单元格
148 if (isMerge != null) {
149 String rs = getMergedRegionValue(sheet, row.getRowNum(), c.getColumnIndex());
150 j= j+isMerge;
151 objList.add(rs);
152 } else {
153 objList.add(getCellValue(c));
154 }
155
156 }
157 while (objList.size() < indexNum) {
158 objList.add("");
159 }
160 objArrList.add(objList.toArray());
161 endMills = System.currentTimeMillis();
162 }
163 }
164
165 /**
166 * 判断指定的单元格是否是合并单元格
167 *
168 * @param sheet
169 * @param row 行下标
170 * @param column 列下标
171 * @return
172 */
173 public static Integer isMergedRegion(Sheet sheet, int row, int column) {
174 int sheetMergeCount = sheet.getNumMergedRegions();
175 /*
176 * 得到所bai有的合并单元格 sourceSheet.getNumMergedRegions();
177 * 得到某一个合du并单元格 CellRangeAddress oldRange=sourceSheet.getMergedRegion(i);
178 * 起始行 oldRange.getFirstRow() ;
179 * zhi 结束行oldRange.getLastRow()
180 * 起始列oldRange.getFirstColumn()
181 * 结束列oldRange.getLastColumn()*/
182 for (int i = 0; i < sheetMergeCount; i++) {
183 CellRangeAddress range = sheet.getMergedRegion(i);
184 int firstColumn = range.getFirstColumn();
185 int lastColumn = range.getLastColumn();
186 int firstRow = range.getFirstRow();
187 int lastRow = range.getLastRow();
188 if (row >= firstRow && row <= lastRow) {
189 if (column >= firstColumn && column <= lastColumn) {
190 return lastColumn - firstColumn;
191 }
192 }
193 }
194 return null;
195 }
196
197 /**
198 * 获取合并单元格的值
199 *
200 * @param sheet
201 * @param row
202 * @param column
203 * @return
204 */
205 public static String getMergedRegionValue(Sheet sheet, int row, int column) {
206 int sheetMergeCount = sheet.getNumMergedRegions();
207
208 for (int i = 0; i < sheetMergeCount; i++) {
209 CellRangeAddress ca = sheet.getMergedRegion(i);
210 int firstColumn = ca.getFirstColumn();
211 int lastColumn = ca.getLastColumn();
212 int firstRow = ca.getFirstRow();
213 int lastRow = ca.getLastRow();
214
215 if (row >= firstRow && row <= lastRow) {
216 if (column >= firstColumn && column <= lastColumn) {
217 Row fRow = sheet.getRow(firstRow);
218 Cell fCell = fRow.getCell(firstColumn);
219 return getCellValue(fCell);
220 }
221 }
222 }
223
224 return null;
225 }
226
227 /**
228 * 获取单元格的值
229 *
230 * @param cell
231 * @return
232 */
233 public static String getCellValue(Cell cell) {
234
235 if (cell == null) return "";
236
237 if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
238
239 return cell.getStringCellValue();
240
241 } else if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
242
243 return String.valueOf(cell.getBooleanCellValue());
244
245 } else if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
246
247 return cell.getCellFormula();
248
249 } else if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
250
251 return String.valueOf(cell.getNumericCellValue());
252
253 }
254 return "";
255 }
256 }
测试类:

1 @Test
2 public void test4(){
3 String str1 = "";//第一张excel路径
4 String str2 = "";//第二张excel路径
5 //调用工具类
6 PoiUtils.compareExcelAWithExcelB(str1,str2);
7 }

最新文章

  1. jQuery MiniUI开发系列之:Ajax处理超时、服务端错误
  2. OC 类方法,对象方法,构造方法以及instancetype和id的异同
  3. linux redhat6.4安装oracle11g
  4. MongoDB (九) MongoDB 投影
  5. js中数组操作
  6. Linux下用来获取各种系统信息的C++类
  7. poj 1206
  8. 关于 firefox 无法在 passport.csdn.net 找到该服务器
  9. Dining(最大流)
  10. Qt 释放新建窗口资源
  11. bfs UESTC 381 Knight and Rook
  12. 51Nod--1049最大子段和
  13. EBS业务学习之应收管理
  14. 从.Net到Java学习第四篇——spring boot+redis
  15. [CQOI2016]手机号码
  16. Centos下SFTP双机高可用环境部署记录
  17. 基于SVM的python简单实现验证码识别
  18. 第8月第19天 django rest
  19. java.lang.IllegalArgumentException: Service not registered
  20. day17&lt;集合框架+&gt;

热门文章

  1. Vue09 事件
  2. Listen 1音乐播放器
  3. (二) MdbCluster分布式内存数据库——分布式架构1
  4. STM32F4库函数初始化系列:PWM输出
  5. 微信小程序分类菜单激活状态跟随列表滚动自动切换
  6. 机器学习-集成学习LightGBM
  7. Centos7作为VNCserver,本地使用VNCViewer连接
  8. JZOJ 4212. 【五校联考1day2】我想大声告诉你
  9. 读论文SRCNN:Learning a Deep Convolutional Network for Image Super-Resolution
  10. webgl 系列 —— 初识 WebGL