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. CentOS7安装了图形界面为默认如何修改默认登录到控制台

    在安装的时候,选择了图形界面安装,一段时间后,想还是直接登录到控制台,需要的时候在手动登录到图形界面, 在CentOS7中的设置方法不同与之前的版本 在之前的版本中是修改配置文件 sudo nano ...

  2. RocketMQ - 生产者原理

    https://rocketmq.apache.org/ Apache RocketMQ是一款开源的.分布式的消息投递与流数据平台.出生自阿里巴巴,在阿里巴巴内部经历了3个版本后,作为Apache 顶 ...

  3. Ribbon服务调用+负载均衡(入门)

    1.Ribbon Ribbon中文:(用于捆绑或装饰的)带子; 丝带; 带状物; 主要功能是提供客户端的软件负载均衡算法和服务调用 Ribbon已经进入了维护模式了,但是Ribbon仍然被广泛使用中 ...

  4. UEFI引导安装UBUNUT

    1.引导方式一定要选UEFI,否则一些显卡驱动将不能安装 2.安装的时候,要在第四个界面,也就是选择覆盖安装还是保留双系统的那个界面,选择其他,一定要自己分区 3.分区: 4.一共5个重要分区: 1. ...

  5. 部署Kubernetes v1.22.10高可用集群

    一.概述 Kubernetes集群控制平面(Master)节点右数据库服务(Etcd)+其它服务组件(Apiserver.Controller-manager.Scheduler等)组成:整个集群系统 ...

  6. Bypass disable_functions 食用方法

    Bypass disable_functions 食用方法 目录 Bypass disable_functions 食用方法 1 上传Payload 2 直接使用sh反弹shell 3 上传 Payl ...

  7. 首个比较研究表明维持期强柱患者减量续用TNFi疗效尚佳且药费省

    首个比较研究表明维持期强柱患者减量续用TNFi疗效尚佳且药费省 Zavada J, et al. Ann Rheum Dis. 2016,75: 96-102. 电邮发布日期: 2016年5月4日 关 ...

  8. el-input只能输入数字和小数

    1.oninput ="value=value.replace(/[^\d]/g,'')" //只能输入数字 2.oninput ="value=value.replac ...

  9. 基于Python的OpenGL 02 之着色器

    1. 概述 本文基于Python语言,描述OpenGL的着色器 环境搭建以及绘制流程可参考: 基于Python的OpenGL 01 之Hello Triangle - 当时明月在曾照彩云归 - 博客园 ...

  10. java-tocsv

    1.依赖 <dependencies> <dependency> <groupId>org.apache.poi</groupId> <artif ...