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 }

java对excel的操作的更多相关文章

  1. Java实现Excel的操作

    JAVA EXCEL API: 开源项目,通过它Java开发人员可以读取Excel文件的内容.创建新的Excel文件.更新已经存在的Excel文件.使用该API非Windows操作系统也可以通过纯Ja ...

  2. Java学习---Excel读写操作

    1.1.1. 简介 Apache POI 使用Apache POI 完成Excel读写操作 Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API ...

  3. EPPLUS之外的选择,EXCEL的操作(NPOI,POI(java))

    NPOI 编辑 NPOI 是 POI 项目的 .NET 版本.POI是一个开源的Java读写Excel.WORD等微软OLE2组件文档的项目. 中文名 NPOI 优    势 传统操作Excel遇到的 ...

  4. java导入导出excel常用操作小结及简单示例

    POI中常用设置EXCEL的操作小结: 操作excel如下 HSSFWorkbook wb = new HSSFWorkbook();  //创建一个webbook,对应一个Excel文件 HSSFS ...

  5. Java 使用jxl对Excel进行操作

    一个作业需要对excel数据进行离散化,想起好像可以用java对excel数据进行处理,因此学习使用, 在网上也有很多人对这个内容解释,但是还是觉得有些杂,就自己整理了一些别人写的内容. /***** ...

  6. 【POI】java对excel的读写操作

    在工作中需要将mongo中的数据导出到excel中,所以根据需要学习了poi.以下为学习内容的总结: 1.POI是什么? poi是Apache团队开发的专门面对用java处理Excel文档的工具. 官 ...

  7. java 使用jxl poi 操作excel

    java操作excel  创建.修改 xls 文件 JAVA操作Excel文件 Java生成和操作Excel文件 java导出Excel通用方法 Java 实现导出excel表 POI Java PO ...

  8. JAVA对Excel文件进行操作

    JAVA EXCEL API:是一开放源码项目,通过它Java开发人员可以读取Excel文件的内容.创建新的Excel文件.更新已经存在的Excel文件.使用该API非Windows操作系统也可以通过 ...

  9. Java 实现Excel的简单读取操作

    JAVA实现Excel表单的简单读取操作 实现Excel表单的简单读取操作,首先要导入相关的jar包: 如图所示: 此处贴上代码: public static List<List<Stri ...

  10. Java导出excel

    一.介绍 常常有客户这样子要求:你要把我们的报表直接用Excel打开(电信系统.银行系统).或者是:我们已经习惯用Excel打印.这样在我们实际的开发中,很多时候需要实现导入.导出Excel的应用. ...

随机推荐

  1. vivo官网App模块化开发方案-ModularDevTool

    作者:vivo 互联网客户端团队- Wang Zhenyu 本文主要讲述了Android客户端模块化开发的痛点及解决方案,详细讲解了方案的实现思路和具体实现方法. 说明:本工具基于vivo互联网客户端 ...

  2. P31_全局配置 - window - 设置上拉触底的距离

    window 设置上拉触底的距离 概念:上拉触底是移动端的专有名词,通过手指在屏幕上的上拉滑动操作,从而加载更多数据的行为. 设置步骤: app.json -> window -> 为 o ...

  3. cannot load "mso.dll" vs2008 web开发问题

    已成功解决办法: ①将VS 2008安装包WCUWebDesignerCoreWebDesignerCore.exe提取并重新安装: ②将C:Program Files/Common Files/Mi ...

  4. Xlight安装与使用

    Xlight安装与使用 一.Xlight安装 下载Xlight安装包,点击安装,默认就可以,下一步 点击左上角增加虚拟服务器,IP地址为本机服务器IP地址 右键点击新添加的虚拟服务器,点击虚拟服务器操 ...

  5. [EULAR文摘] 滑膜HIF-1a与类风湿关节炎的关节破坏

    滑膜HIF-1a与类风湿关节炎的关节破坏 Wei XN, et al. EULAR 2015. Present ID: OP0070. 背景:低氧诱导因子(HIF)-1α是缺氧条件下细胞反应的一个关键 ...

  6. C#辗转相除法输出最大公约数

    void main() { int r, m, n, t; scanf_s("%d\n%d", &m, &n); if (m < n) { t = m; m ...

  7. 下拉刷新 get请求 post请求 onLoad

       "enablePullDownRefresh": true 下拉刷新之后背景颜色  "backgroundColor": "#efefef&qu ...

  8. 钉钉h5开发流程

    1.先在钉钉开发者后台 https://login.dingtalk.com/oauth2/challenge.htm?redirect_uri=https%3A%2F%2Fopen-dev.ding ...

  9. 区块链leveldb数据库安装

    一.首先,需要在电脑上安装boost库. 下载地址在这里,下载压缩包之后解压,Index of main/release/1.79.0/source. 解压完成后在解压好的文件夹里面进入cmd,之后运 ...

  10. 下载nvm并安装vue环境

    nvm下载地址 https://github.com/coreybutler/nvm-windows/releases 直接下载 nvm-setup.zip 到任意文件夹下,双击安装 安装过程会提示 ...