Java poi解析excel
首先先添加依赖
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poi-ooxmlartifactId>
<version>3.17version>
dependency>
代码解析excel,这里借鉴了以为博主的源码请看这里https://blog.csdn.net/weixin_44001965/article/details/102501772
package com.wrq.testexcel;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class ParseExcel {
/**
* 解析文件的方法
*@param inputStream 文件输入流,要解析的Excel文件输入流
*@param suffix 后缀名,xls或xlsx,代码决定使用什么方式解析Excel
*@param startRow 从第几行开始读取数据
*@return List 集合中的一个元素对应一行解析的数据
* 元素为字符串数组类型,数组中的每一个元素对应一列数据
* @throws IOException
*/
public static List<String[]> parseExcel(InputStream inputStream, String suffix, int startRow) throws IOException {
//定义Excel对象变量
Workbook workbook=null;
//判断后缀 决定使用的解析方式,决定如何创建具体的对象
if("xls".equals(suffix)) {
//2003版的解析方式
workbook=new HSSFWorkbook(inputStream);
}else if("xlsx".equals(suffix)) {
//2007
workbook=new XSSFWorkbook(inputStream);
}else {
//未知内容
return null;
}
//获取工作表,Excel分为若干个表,sheet
Sheet sheet = workbook.getSheetAt(0);//得到第一个表格sheet
if(sheet==null) {
return null;
}
//获取表格中最后一行的行号
int lastRowNum = sheet.getLastRowNum();
//最后一行的行号大于startRow
if(lastRowNum<=startRow) {
return null;
}
List<String[]> result=new ArrayList<String[]>();
//定义行变量和单元格变量
Row row=null;
Cell cell=null;
//循环读取
for (int rowNum = startRow; rowNum <= lastRowNum; rowNum++) {
row=sheet.getRow(rowNum);
//获取当前行的第一列和最后一列的标记
short firstCellNum = row.getFirstCellNum();
short lastCellNum = row.getLastCellNum();
if(lastCellNum!=0) {
String[] rowArray=new String[lastCellNum];
for(int cellNum=firstCellNum;cellNum<lastCellNum;cellNum++) {
//拿到单元格的值
cell=row.getCell(cellNum);
//判断单元格是否有数据
if(cell==null) {
rowArray[cellNum]=null;
}else {
rowArray[cellNum]=parseCell(cell);
}
}
result.add(rowArray);
}
}
return result;
}
/**
* 解析单元格数据(返回字符串)
*/
private static String parseCell(Cell cell) {
String cellStr=null;
//判断单元格的类型
switch (cell.getCellTypeEnum()) {
case STRING :
//字符串类型单元格
cellStr=cell.getRichStringCellValue().toString();
break;
case BLANK :
//空数据
cellStr="";
break;
case NUMERIC :
//数字类型 包含日期、时间、数字
//判断日期【年月日2016-12-20 | 时分10:20】类型
if(HSSFDateUtil.isCellDateFormatted(cell)) {
//判断具体类型,是日期还是时间
SimpleDateFormat sdf=null;
if(cell.getCellStyle().getDataFormat()== HSSFDataFormat.getBuiltinFormat("h:mm")) {
//时间
sdf=new SimpleDateFormat("HH:mm");
}else {
//日期
sdf=new SimpleDateFormat("yyyy-MM-dd");
}
Date temp = cell.getDateCellValue();
cellStr=sdf.format(temp);
}else {
//数字
double temp=cell.getNumericCellValue();
//数字格式化工具
DecimalFormat format=new DecimalFormat();
//查看单元格中的具体样式类型
String formatStr=cell.getCellStyle().getDataFormatString();
if(formatStr.equals("General")) {
/**
* 定义格式化正则
* 保留一位小数 #.#
* 保留两位小数#.##
*/
format.applyPattern("#");
}
cellStr=format.format(temp);
}
break;
default:
cellStr="";
}
return cellStr;
}
}
接下来就是根据自己的业务需求对excel惊醒修改,这里是根据我自己的需求为例:需求:将一张表的A列里数字代码的内容根据数字代码对应关系修改成B列的中文名成,然后将这两列中带有关键字的一行在最后一个单元格中添加“是”
package com.wrq.testexcel;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.*;
import java.util.*;
public class UpdateExcel {
public static void main(String[] args) throws IOException {
InputStream inputStream=new FileInputStream("D:/testFile/REQMT20210827180243_sys_office(1)(1)(1).xlsx");
String suffix="xlsx";
int startRow=1;
//读取文件获得数据
List<String[]> alllist = ParseExcel.parseExcel(inputStream, suffix, startRow);
//存ID和NAME
Map<String,String> idAndName=new HashMap<>();
String[] IDS={};
List<String> stringList=null;
//存新数据
List<String> PARENT_IDSList=new ArrayList<>();
//先将Id和name全部存入到另一个集合里
for (String[] str:alllist) {
stringList= Arrays.asList(str);
String ID = stringList.get(0);
String NAME = stringList.get(3);
idAndName.put(ID,NAME);
}
for (String[] str:alllist) {
stringList = Arrays.asList(str);
//找到需要修改的一列
IDS = stringList.get(2).split(",");
for (int i = 0; i < IDS.length; i++) {
String id = IDS[i];
if (!Objects.isNull(id)) {
//更改为需要的数据
String name = idAndName.get(id);
if (null==name){
IDS[i]=id;
}else {
IDS[i]=name;
}
}
}
//重新拼接新数据
String PARENT_IDS=String.join(",",IDS);
PARENT_IDSList.add(PARENT_IDS);
}
motif(PARENT_IDSList);
//System.out.println(alllist.size());
inputStream.close();
}
public static void motif(List<String> PARENT_IDSList) throws IOException {
//根据需求定义关键字
List<String > senWords=Arrays.asList("美容,美发,整容,大客户,健身".split(","));
InputStream inputStream=new FileInputStream("D:/testFile/REQMT20210827180243_sys_office(1)(1)(1).xlsx");
OutputStream outputStream=new FileOutputStream("D:/testFile/REQMT20210827180243_sys_office.xlsx");
//获取文件
Workbook workbook=new XSSFWorkbook(inputStream);
//获取excel
Sheet sheet = workbook.getSheet("Sheet1");
int lastRowNum = sheet.getLastRowNum();
for (int i=1;i<lastRowNum;i++){
//获取每一行
Row row = sheet.getRow(i);
if (null!=row){
//获取需要的单元格
Cell cell = row.getCell(2);
String IDS = PARENT_IDSList.get(i-1);
//修改内容
if (null!=IDS){
cell.setCellValue(IDS);
}
Cell govCell = row.getCell(15);
if (null==govCell){
govCell= row.createCell(15);
}
//根据关键字修改内容
Cell nameCell= row.getCell(3);
String name = nameCell.getStringCellValue();
for (String words: senWords) {
if (IDS.contains(words)){
govCell.setCellValue("是");
}
if (name.contains(words)){
govCell.setCellValue("是");
}
}
}
}
workbook.write(outputStream);
inputStream.close();
outputStream.close();
}
}