java对excel的操作
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的操作的更多相关文章
- Java实现Excel的操作
JAVA EXCEL API: 开源项目,通过它Java开发人员可以读取Excel文件的内容.创建新的Excel文件.更新已经存在的Excel文件.使用该API非Windows操作系统也可以通过纯Ja ...
- Java学习---Excel读写操作
1.1.1. 简介 Apache POI 使用Apache POI 完成Excel读写操作 Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API ...
- EPPLUS之外的选择,EXCEL的操作(NPOI,POI(java))
NPOI 编辑 NPOI 是 POI 项目的 .NET 版本.POI是一个开源的Java读写Excel.WORD等微软OLE2组件文档的项目. 中文名 NPOI 优 势 传统操作Excel遇到的 ...
- java导入导出excel常用操作小结及简单示例
POI中常用设置EXCEL的操作小结: 操作excel如下 HSSFWorkbook wb = new HSSFWorkbook(); //创建一个webbook,对应一个Excel文件 HSSFS ...
- Java 使用jxl对Excel进行操作
一个作业需要对excel数据进行离散化,想起好像可以用java对excel数据进行处理,因此学习使用, 在网上也有很多人对这个内容解释,但是还是觉得有些杂,就自己整理了一些别人写的内容. /***** ...
- 【POI】java对excel的读写操作
在工作中需要将mongo中的数据导出到excel中,所以根据需要学习了poi.以下为学习内容的总结: 1.POI是什么? poi是Apache团队开发的专门面对用java处理Excel文档的工具. 官 ...
- java 使用jxl poi 操作excel
java操作excel 创建.修改 xls 文件 JAVA操作Excel文件 Java生成和操作Excel文件 java导出Excel通用方法 Java 实现导出excel表 POI Java PO ...
- JAVA对Excel文件进行操作
JAVA EXCEL API:是一开放源码项目,通过它Java开发人员可以读取Excel文件的内容.创建新的Excel文件.更新已经存在的Excel文件.使用该API非Windows操作系统也可以通过 ...
- Java 实现Excel的简单读取操作
JAVA实现Excel表单的简单读取操作 实现Excel表单的简单读取操作,首先要导入相关的jar包: 如图所示: 此处贴上代码: public static List<List<Stri ...
- Java导出excel
一.介绍 常常有客户这样子要求:你要把我们的报表直接用Excel打开(电信系统.银行系统).或者是:我们已经习惯用Excel打印.这样在我们实际的开发中,很多时候需要实现导入.导出Excel的应用. ...
随机推荐
- python装饰器拦截方法执行
import time def log(delay=0): def decorator(func): def wrapper(*args, **kwargs): """我 ...
- LinkedHashmap简要说明
https://segmentfault.com/a/1190000012964859 LinkedHashMap 继承自 HashMap,在 HashMap 基础上,通过维护一条双向链表,解决了 H ...
- .net core 前端传递参数有值 后端接收到的数据却是null
1.问题分析 在做接口测试时,偶然出现了前端输出有值,但是后端断点调试时却出现接收参数总是为null的情况 2.解决办法 前端打印log,看前端的每一个传值的数据类型,与后端请求参数类进行认真的一一比 ...
- Zstack使用经验系列1-安装的网络配置
https://www.zstack.io/help/product_manuals/maintenance_manual/4.html 在官网上从这里有详细的安装,读者可以从上面链接开始起步装起来. ...
- 零基础解读ChatGPT:对人类未来工作是威胁还是帮助?
摘要:火到现在的ChatGPT到底是什么?它背后有哪些技术?对于我们的工作和生活会有啥影响?快来一起了解吧~ 本文分享自华为云社区<零基础解读ChatGPT:对人类未来工作是威胁还是帮助?> ...
- 读论文SRCNN:Learning a Deep Convolutional Network for Image Super-Resolution
Learning a Deep Convolutional Network for Image Super-Resolution SRCNN是深度学习应用于SR领域的开山之作. 论文 2014 ECC ...
- 2014-12-2 Z字形扫描
问题描述 试题编号: 201412-2 试题名称: Z字形扫描 时间限制: 2.0s 内存限制: 256.0MB 问题描述: 问题描述 在图像编码的算法中,需要将一个给定的方形矩阵进行Z字形扫描(Zi ...
- 一个基于 gin+ grpc + etcd 等框架开发的小栗子
一.标准的项目结构 首先我们看一个标准的项目结构是什么样子的,github 上给出的一个示例:golang-standards/project-layout 二.服务注册与发现流程 三.示例代码 项目 ...
- js中Math.floor、Math.ceil、Math.round和parseInt小数取整小结
虽然知道结果都可以返回一个整数,但是四者的区别尤其是关于-0.5的取整情况貌似还是需要注意一下一.Math.floor(向下取整) 作用:返回小于等于参数的最大整数. eg: Math.floor(5 ...
- PostGIS之空间投影
1. 概述 PostGIS 是PostgreSQL数据库一个空间数据库扩展,它添加了对地理对象的支持,允许在 SQL 中运行空间查询 PostGIS官网:About PostGIS | PostGIS ...