一、使用Apache的POI操作Excel需要的jar包
注意:POI的jar不同版本要求jdk版本不同,根据自己jdk版本选择不同版本。我用的jdk1.6,下载的3.17版本的POI。
其中commons-collections4是poi的依赖jar包,poi-ooxml-schemas和xmlbeans是poi-ooxml的依赖jar包,如果使用maven自动下载只在pom文件中添加poi和poi-ooxml就可以,如果自己下载jar包添加到项目中则5个都需要下载并添加。
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.1</version>
</dependency>
二、实现Excel的读写
操作xls后缀的Excel用HSSFWorkbook,操作xlsx后缀的Excel用XSSFWorkbook或者SXSSFWorkbook。SXSSFWorkbook可以指定多少条数据保存在内存中,其余数据保存在磁盘中,防止写入数据太大导致内存溢出。关于两种Excel区别和三个类的具体区别可另行百度。
注意:使用XSSFWorkbook读取xlsx类型Excel时,会将Excel所有内容一次性加载放到内存中包括空行也会读取出来,如果数据量巨大或者有巨多空行时会比较耗时。此次写入只判断了读取到的是否是空行,没有研究怎么快速读取大数据量的xlsx。
1、读取Excel
方法中调用的其他方法可在HandleFile类完整内容中寻找
/**
* 将Excel的标题行内容放入list中,获取所有内容可循环所有行,每一行在循环所有列
* @param path
* @param filename
* @param fileType
*/
public void readExcel(String path, String filename, String fileType) {
Workbook wb = null;
try {
wb = getWorkbook(wb,path,filename,fileType);
Sheet sheet = wb.getSheetAt(0);// 获取第一个sheet页
int countrow = sheet.getPhysicalNumberOfRows();// 获取sheet页的总行数
if (countrow==0) { throw new Exception("Excel读取到的总行数为0"); }
Row row0 = sheet.getRow(0);// 获取第0行的标题行
List<String> titleList = new ArrayList<String>(); //保存标题
for (int k = 0; k < row0.getPhysicalNumberOfCells(); k++) {// 循环所有列,放入list中
Cell cell = row0.getCell(k);
titleList.add(getString(cell));
}
} catch (Exception e) {
addMsg("Excel在读取内容时出错:"+e+"\r\n***********************************************************************************************************************************************************");
} finally {
if (wb!=null) { try{wb.close(); }catch(Exception e) {}}
}
}
2、写入Excel
方法中调用的其他方法可在HandleFile类完整内容中寻找
/**
* 将list中的内容写入Excel的一行中
* @param path 文件路径
* @param fileName 写入Excel的文件名带后缀
* @param fileType 写入Excel的文件类型,xls、xlsx
* @param titleList 要写入Excel的list数据
*/
public void writeRxcel(String path, String fileName, String fileType, List<String> titleList) {
Workbook wb = null; Sheet sheet = null;
try {
File file = new File(path+fileName);
if (file.exists()) {// 追加
wb = getWorkbook(wb, path, fileName, fileType);
sheet = wb.getSheetAt(0);
} else {// 新创建并写入
file.createNewFile();// 创建文件
wb = createWorkbook(wb, fileType);
sheet = wb.createSheet();
}
int numRow = sheet.getPhysicalNumberOfRows();// 当前sheet页有多少行
Row row = sheet.createRow(numRow);// 在下一行创建row对象
for (int k = 0; k < titleList.size(); k++) {
row.createCell(k, CellType.STRING).setCellValue(titleList.get(k));
}
FileOutputStream fout = new FileOutputStream(file);
wb.write(fout);
fout.close();
} catch (Exception e) {
//e.printStackTrace();
addMsg("写入Excel时出错:"+e+"\r\n***********************************************************************************************************************************************************");
}
}
三、Excel的拆分
将Excel按某一列不同的值拆分成不同的Excel,相同的值保存在相同的Excel中。将新生成的Excel和拆分的Excel打包在一个zip中。
方法中调用的其他方法可在HandleFile类完整内容中寻找
/**
* 将Excel按某一列不同的值拆分成不同的Excel,相同的值保存在相同的Excel中。将新生成的Excel和拆分的Excel打包在一个zip中
* @param path 文件所在路径
* @param filename 文件名带后缀,文件名中带着_日期,例如拆分Excel_20220829.xlsx
* @param fileType 文件类型
* @param fileZip 创建的压缩文件名
* @return
*/
public String handlingExcel(String path, String filename, String fileType, String fileZip) {
long sj1 = System.currentTimeMillis(); String re = "OK"; Workbook wb = null;
try {
//获取文件名中的日期
String strDate = filename.substring(filename.lastIndexOf("_")+1, filename.lastIndexOf("."));
int splitNum = -1;
Map<Object,List<Object>> map = new HashMap<Object,List<Object>>();
wb = getWorkbook(wb,path,filename,fileType);
Sheet sheet = wb.getSheetAt(0);
int countrow = sheet.getPhysicalNumberOfRows();// 总行数
if (countrow==0) { throw new Exception("Excel读取到的总行数为0"); }
Row row0 = sheet.getRow(0);//第0行是标题
List<Object> titleList = new ArrayList<Object>();// 保存Excel的标题行所有标题
for (int k = 0; k < row0.getPhysicalNumberOfCells(); k++) {// 循环所有列,放入list中
Cell cell = row0.getCell(k);
titleList.add(getString(cell));
if ("AAB301".equals(getString(cell))) {// 要按哪一列进行拆分的那一列的标题名
splitNum = k;
}
}
if (splitNum<0) { splitNum=1; } // 没有匹配的标题名默认用第二列作为拆分,也可在此抛出异常
List<Object> rowList = new ArrayList<Object>(); List<Object> cellList = new ArrayList<Object>();
for (int i = 1; i < countrow; i++) {//数据从第1行开始
Row row = sheet.getRow(i);
if (isEmptyRow(row)) { continue; }// 判断是否是空行
Cell titleCell = row.getCell(splitNum);
String aab301 = getString(titleCell);
rowList = new ArrayList<Object>(); cellList = new ArrayList<Object>();// 每次都先清除列数据list中的数据,用clear方法会导致其他引用list的地方也变成空
for(int j = 0; j < row.getPhysicalNumberOfCells(); j++) {// 循环所有列,放入list中
Cell cell = row.getCell(j);
cellList.add(getString(cell));
}
/**
* map中key保存的是要拆分的列中不同的值,value保存的是rowList数据对应Excel中的行数据。
* rowList中保存的是cellList相当于保存了拆分列等于key的所有行,cellList保存的是一行中所有列的数据。
*/
if (map.containsKey(aab301+"_"+strDate)) {
rowList = map.get(aab301+"_"+strDate);
rowList.add(cellList);
map.put(aab301+"_"+strDate, rowList);
if (rowList.size() >= 100) {// 每一百条写入一次Excel
writeExcel(path,aab301+"_"+strDate+"."+fileType,fileType,rowList,titleList);
//清空map中的list
map.put(aab301+"_"+strDate, new ArrayList<Object>());
}
} else {
rowList.add(cellList);
map.put(aab301+"_"+strDate, rowList);
}
}
// 循环map,将不足100条的也写入Excel中
Set<Map.Entry<Object, List<Object>>> entries = map.entrySet();
Iterator<Map.Entry<Object, List<Object>>> iterators = entries.iterator();
while (iterators.hasNext()) {
Map.Entry<Object, List<Object>> next = iterators.next();
writeExcel(path,String.valueOf(next.getKey())+"."+fileType,fileType,next.getValue(),titleList);
}
// 创建压缩文件
zip(path, path+fileZip);
} catch (Exception e) {
re = e.toString();
//e.printStackTrace();
addMsg("拆分Excel在读取内容时出错:"+e+"\r\n***********************************************************************************************************************************************************");
} finally {
if (wb!=null) { try{wb.close(); }catch(Exception e) {}}
}
addMsg("拆分Excel结束,用时:"+((System.currentTimeMillis() - sj1)+"ms")+"\r\n***********************************************************************************************************************************************************");
return re;
}
四、Excel的合并
方法中调用的其他方法可在HandleFile类完整内容中寻找
/**
* 将多个Excel合并成一个Excel
* @param path 压缩文件路径
* @param filename 压缩文件zip文件名带后缀
* @param fileDownLoad 要生成的Excel文件名带后缀
* @return
*/
public String handlingZip(String path, String filename, String fileDownLoad) {
long sj1=System.currentTimeMillis(); String re = "OK";
try {
//解压文件
unzip(path+filename, path);
List<File> files = new ArrayList<File>();
getAllFiles(files,path);
mergeFile(path,fileDownLoad,files);
} catch (Exception e) {
addMsg("合并Excel时出错:"+e+"\r\n");
}
addMsg("合并Excel结束,用时:"+((System.currentTimeMillis() - sj1)+"ms")+"\r\n***********************************************************************************************************************************************************");
return re;
}
五、测试用的类HandleFile
其中压缩文件用到的jar包
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.8.2</version>
</dependency>
HandleFile类完整内容
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DateUtil;
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.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Expand;
import org.apache.tools.ant.taskdefs.Zip;
public class HandleFile {
public static StringBuffer strMsg = new StringBuffer();
public void addMsg(String s){ strMsg.append(getTime()+","+s+"\n"); if (strMsg.length()>200000) strMsg.delete(0,100000); }
public String getTime() { return getTime(System.currentTimeMillis(), "yyyyMMddHHmmss"); }
public String getTime(long time, String format) { if (time <= 0) { return ""; } else { return new SimpleDateFormat(format).format(new Date(time)); } }
/**
* 将Excel的标题行内容放入list中
* @param path
* @param filename
* @param fileType
*/
public void readExcel(String path, String filename, String fileType) {
Workbook wb = null;
try {
wb = getWorkbook(wb,path,filename,fileType);
Sheet sheet = wb.getSheetAt(0);// 获取第一个sheet页
int countrow = sheet.getPhysicalNumberOfRows();// 获取sheet页的总行数
if (countrow==0) { throw new Exception("Excel读取到的总行数为0"); }
Row row0 = sheet.getRow(0);// 获取第0行的标题行
List<String> titleList = new ArrayList<String>(); //保存标题
for (int k = 0; k < row0.getPhysicalNumberOfCells(); k++) {// 循环所有列,放入list中
Cell cell = row0.getCell(k);
titleList.add(getString(cell));
}
} catch (Exception e) {
addMsg("拆分Excel在读取内容时出错:"+e+"\r\n***********************************************************************************************************************************************************");
} finally {
if (wb!=null) { try{wb.close(); }catch(Exception e) {}}
}
}
/**
* 将list中的内容写入Excel的一行中
* @param path 文件路径
* @param fileName 写入Excel的文件名带后缀
* @param fileType 写入Excel的文件类型,xls、xlsx
* @param titleList 要写入Excel的list数据
*/
public void writeRxcel(String path, String fileName, String fileType, List<String> titleList) {
Workbook wb = null; Sheet sheet = null;
try {
File file = new File(path+fileName);
if (file.exists()) {// 追加
wb = getWorkbook(wb, path, fileName, fileType);
sheet = wb.getSheetAt(0);
} else {// 新创建并写入
file.createNewFile();// 创建文件
wb = createWorkbook(wb, fileType);
sheet = wb.createSheet();
}
int numRow = sheet.getPhysicalNumberOfRows();// 当前sheet页有多少行
Row row = sheet.createRow(numRow);// 在下一行创建row对象
for (int k = 0; k < titleList.size(); k++) {
row.createCell(k, CellType.STRING).setCellValue(titleList.get(k));
}
FileOutputStream fout = new FileOutputStream(file);
wb.write(fout);
fout.close();
} catch (Exception e) {
//e.printStackTrace();
addMsg("写入Excel时出错:"+e+"\r\n***********************************************************************************************************************************************************");
}
}
/**
* 将Excel按某一列不同的值拆分成不同的Excel,相同的值保存在相同的Excel中。将新生成的Excel和拆分的Excel打包在一个zip中
* @param path 文件所在路径
* @param filename 文件名带后缀,文件名中带着_日期,例如拆分Excel_20220829.xlsx
* @param fileType 文件类型
* @param fileZip 创建的压缩文件名
* @return
*/
public String handlingExcel(String path, String filename, String fileType, String fileZip) {
long sj1=System.currentTimeMillis(); String re = "OK"; Workbook wb = null;
try {
String strDate = filename.substring(filename.lastIndexOf("_")+1, filename.lastIndexOf("."));
int splitNum = -1;
Map<Object,List<Object>> map = new HashMap<Object,List<Object>>();
wb = getWorkbook(wb,path,filename,fileType);
Sheet sheet = wb.getSheetAt(0);
int countrow = sheet.getPhysicalNumberOfRows();// 总行数
if (countrow==0) { throw new Exception("Excel读取到的总行数为0"); }
Row row0 = sheet.getRow(0);//第0行是标题
List<Object> titleList = new ArrayList<Object>();
for (int k = 0; k < row0.getPhysicalNumberOfCells(); k++) {// 循环所有列,放入list中
Cell cell = row0.getCell(k);
titleList.add(getString(cell));
if ("AAB301".equals(getString(cell))) {// 要按哪一列进行拆分的那一列的标题名
splitNum = k;
}
}
if (splitNum<0) { splitNum=1; }
List<Object> rowList = new ArrayList<Object>(); List<Object> cellList = new ArrayList<Object>();
for (int i = 1; i < countrow; i++) {//数据从第1行开始
Row row = sheet.getRow(i);
if (isEmptyRow(row)) { continue; }
Cell titleCell = row.getCell(splitNum);
String aab301 = getString(titleCell);
rowList = new ArrayList<Object>(); cellList = new ArrayList<Object>();// 每次都先清除列数据list中的数据,用clear方法会导致其他引用list的地方也变成空
for(int j = 0; j < row.getPhysicalNumberOfCells(); j++) {// 循环所有列,放入list中
Cell cell = row.getCell(j);
cellList.add(getString(cell));
}
if (map.containsKey(aab301+"_"+strDate)) {
rowList = map.get(aab301+"_"+strDate);
rowList.add(cellList);
map.put(aab301+"_"+strDate, rowList);
if (rowList.size() >= 100) {// 每一百条写入一次Excel
writeExcel(path,aab301+"_"+strDate+"."+fileType,fileType,rowList,titleList);
//清空map中的list
map.put(aab301+"_"+strDate, new ArrayList<Object>());
}
} else {
rowList.add(cellList);
map.put(aab301+"_"+strDate, rowList);
}
}
// 循环map,将不足100条的也写入Excel中
Set<Map.Entry<Object, List<Object>>> entries = map.entrySet();
Iterator<Map.Entry<Object, List<Object>>> iterators = entries.iterator();
while (iterators.hasNext()) {
Map.Entry<Object, List<Object>> next = iterators.next();
writeExcel(path,String.valueOf(next.getKey())+"."+fileType,fileType,next.getValue(),titleList);
}
// 创建压缩文件
zip(path, path+fileZip);
} catch (Exception e) {
re = e.toString();
//e.printStackTrace();
addMsg("拆分Excel在读取内容时出错:"+e+"\r\n***********************************************************************************************************************************************************");
} finally {
if (wb!=null) { try{wb.close(); }catch(Exception e) {}}
}
addMsg("拆分Excel结束,用时:"+((System.currentTimeMillis() - sj1)+"ms")+"\r\n***********************************************************************************************************************************************************");
return re;
}
public Workbook createWorkbook(Workbook wb, String fileType) {
try {
if ("xls".equals(fileType)) {
wb = new HSSFWorkbook();
} else if ("xlsx".equals(fileType)) {
wb = new SXSSFWorkbook(100);
}
} catch (Exception e) {
//e.printStackTrace();
addMsg("写入Excel创建Workbook时出错:"+e+"\r\n***********************************************************************************************************************************************************");
}
return wb;
}
/**
* 获取Workbook对象
* @param wb
* @param path 文件路径
* @param fileName 文件名称带后缀
* @param fileType 文件类型,xls、xlsx
* @return
*/
public Workbook getWorkbook(Workbook wb, String path, String fileName, String fileType) {
FileInputStream in = null;
try {
File file = new File(path+fileName);
in = new FileInputStream(file);
if ("xls".equals(fileType)) {
wb = new HSSFWorkbook(in);
} else if ("xlsx".equals(fileType)) {
wb = new XSSFWorkbook(in);// XSSFWorkbook所有数据写在内存中,当数据量太大时容易导致内存溢出。
}
} catch (Exception e) {
//e.printStackTrace();
addMsg("获取Workbook时出错:"+e+"\r\n");
} finally {
if (in != null) { try { in.close(); } catch (Exception e) {} }
}
return wb;
}
public static String getString(Cell cell) {
if (cell == null) {
return "";
} else if (cell.getCellTypeEnum() == CellType.NUMERIC && DateUtil.isCellDateFormatted(cell)) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd");
double value = cell.getNumericCellValue();
Date date = DateUtil.getJavaDate(value);
return sdf.format(date);
} else {
cell.setCellType(CellType.STRING);
return cell.getStringCellValue();
}
}
/**
* 将list中的内容写入到Excel中
* @param path 文件路径
* @param fileName 写入Excel的文件名带后缀
* @param fileType 文件类型
* @param rowList 写入Excel的行数据的list,rowList中每一个值保存的是一个list,里面的list是一个行数据,保存的是列的值
* @param titleList 写入Excel的标题
*/
public void writeExcel(String path, String fileName, String fileType, List<Object> rowList, List<Object> titleList) {
Workbook wb = null; Sheet sheet = null; List<Object> cellList = null;
try {
File file = new File(path+fileName);
if (file.exists()) {// 追加
wb = getWorkbook(wb, path, fileName, fileType);
sheet = wb.getSheetAt(0);
} else {// 新创建并写入
file.createNewFile();// 创建文件
wb = createWorkbook(wb, fileType);
sheet = wb.createSheet();
Row row = sheet.createRow(0);
for (int k = 0; k < titleList.size(); k++) {
row.createCell(k, CellType.STRING).setCellValue(String.valueOf(titleList.get(k)));
}
}
int rowNum = sheet.getPhysicalNumberOfRows();// sheet已有行数
for (int i = 0; i < rowList.size(); i++) {// 循环将行数据list写入sheet页
Row row = sheet.createRow(rowNum++);
cellList = objToList(rowList.get(i));
for(int j = 0; j < cellList.size(); j++) {
row.createCell(j, CellType.STRING).setCellValue(String.valueOf(cellList.get(j)));
}
}
FileOutputStream fout = new FileOutputStream(file);
wb.write(fout);
fout.close();
} catch (Exception e) {
//e.printStackTrace();
addMsg("写入Excel时出错:"+e+"\r\n***********************************************************************************************************************************************************");
}
}
/**
* 将object转成list对象
* @param obj
* @return
*/
public List<Object> objToList(Object obj) {
List<Object> result = new ArrayList<Object>();
if (obj instanceof ArrayList<?>) {
for (Object o : (List<?>) obj) {
result.add(o);
}
}
return result;
}
/**
* 将路径下的文件都压缩
* @param dir 要压缩的路径,将路径下的所有文件压缩在一起
* @param zipfile 压缩后的文件路径加文件名带后缀
*/
public void zip(String dir, String zipfile) {
Zip zip = new Zip();
zip.setProject(new Project());
zip.setEncoding("GBK");
zip.setBasedir(new File(dir));
zip.setDestFile(new File(zipfile));
zip.execute();
}
/**
* 将多个Excel合并成一个Excel
* @param path 压缩文件路径
* @param filename 压缩文件zip文件名带后缀
* @param fileDownLoad 要生成的Excel文件名带后缀
* @return
*/
public String handlingZip(String path, String filename, String fileDownLoad) {
long sj1=System.currentTimeMillis(); String re = "OK";
try {
//解压文件
unzip(path+filename, path);
List<File> files = new ArrayList<File>();
getAllFiles(files,path);
mergeFile(path,fileDownLoad,files);
} catch (Exception e) {
addMsg("合并Excel时出错:"+e+"\r\n");
}
addMsg("合并Excel结束,用时:"+((System.currentTimeMillis() - sj1)+"ms")+"\r\n***********************************************************************************************************************************************************");
return re;
}
/**将压缩文件解压
* @param zipfile 压缩文件路径加文件名 带后缀
* @param dir 解压后保存的路径
*/
public void unzip(String zipfile, String dir) {
Expand exp = new Expand();
exp.setProject(new Project());
exp.setEncoding("GBK");
exp.setSrc(new File(zipfile));
exp.setDest(new File(dir));
exp.execute();
}
/**
* 获取文件夹下所有的文件
* @param files 保存所有文件的list
* @param path 要获取文件的文件夹路径
*/
public void getAllFiles(List<File> files,String path) {
File file = new File(path);
File[] childrenFiles = file.listFiles();//获取路径下的所有文件
if (childrenFiles.length == 0) { return; }
for (File childFile : childrenFiles) {// 遍历所有文件
// 如果是文件,添加到list集合
if (childFile.isFile()) {
files.add(childFile);
} else if(childFile.isDirectory()) { // 如果是文件夹,遍历文件夹下的文件
getAllFiles(files,childFile.getPath());
}
}
}
/**
* 将所有xls和xlsx文件写入到新的文件中
* @param path 新的写入文件的路径
* @param fileZip 新的写入文件的文件名带着后缀
* @param files 所有要写入新文件中的文件
*/
public void mergeFile(String path, String fileZip, List<File> files) {
Workbook wb = null; Workbook wbSrc = null; Sheet sheetWrite = null; Row row0 = null; BufferedOutputStream outputStream = null;
List<String> list = new ArrayList<String>();// 要写入文件的标题
List<String> titleList = null;// 读取文件的标题
try {
wb = new SXSSFWorkbook(getXSSFWorkbook(path+fileZip), 100);
sheetWrite = wb.getSheetAt(0);
row0 = sheetWrite.createRow(0);
File fileSrc = null;
for (int i = 0; i < files.size(); i++) {
fileSrc = files.get(i);
String fileSrcType = fileSrc.getName().substring(fileSrc.getName().lastIndexOf(".")+1);
if("xls".equals(fileSrcType) || "xlsx".equals(fileSrcType)) {
titleList = new ArrayList<String>();
wbSrc = getWorkbook(wbSrc,fileSrc.getPath(),"",fileSrc.getName().substring(fileSrc.getName().lastIndexOf(".")+1,fileSrc.getName().length()));
Sheet sheetSrc = wbSrc.getSheetAt(0);
int numRow = sheetSrc.getPhysicalNumberOfRows();
if (numRow == 0) { break; }// 总行数
Row rowTitle = sheetSrc.getRow(0);// 标题行
for (int k = 0; k < rowTitle.getPhysicalNumberOfCells(); k++) {// 循环所有列,放入list中
Cell cellTitle = rowTitle.getCell(k);
titleList.add(getString(cellTitle));
}
if (list.size() == 0) {
// 写入标题
for (int n = 0; n < titleList.size(); n++) {
row0.createCell(n, CellType.STRING).setCellValue(titleList.get(n));
list.add(titleList.get(n));
}
}
// 遍历所有数据行,写入新文件
boolean isMatch = true;
Row rowWrite = null; Row rowSrc = null;
for (int ii = 1; ii < sheetSrc.getPhysicalNumberOfRows(); ii++) {
rowSrc = sheetSrc.getRow(ii);
if (isEmptyRow(rowSrc)) { continue; }
rowWrite = sheetWrite.createRow(sheetWrite.getPhysicalNumberOfRows());
for (int j = 0; j < titleList.size(); j++) {
isMatch = false;
for (int jj = 0; jj < list.size(); jj++) {
if (titleList.get(j).equals(list.get(jj))) {
rowWrite.createCell(jj, CellType.STRING).setCellValue(getString(rowSrc.getCell(j)));
isMatch = true;
break;
}
}
if (!isMatch) {// 读取文件的标题在写入文件中不存在,在写入文件标题后的列坐标创建新列
list.add(titleList.get(j));
rowWrite.createCell(list.size()-1, CellType.STRING).setCellValue(getString(rowSrc.getCell(j)));
}
}
}
if (wbSrc!=null) { try{wbSrc.close(); }catch(Exception e) {}}
}
}
outputStream = new BufferedOutputStream(new FileOutputStream(path+fileZip));
wb.write(outputStream);
outputStream.flush();
if (outputStream!=null) { try{outputStream.close(); }catch(Exception e) {}}
} catch (Exception e) {
//e.printStackTrace();
addMsg("合并Excel在写入新文件时出错:"+e+"\r\n");
} finally {
if (wb!=null) { try{wb.close(); }catch(Exception e) {}}
if (wbSrc!=null) { try{wbSrc.close(); }catch(Exception e) {}}
if (outputStream!=null) { try{outputStream.close(); }catch(Exception e) {}}
}
// 更新标题
updateTitle(path, fileZip, list);
}
public XSSFWorkbook getXSSFWorkbook(String filePath) {
XSSFWorkbook workbook = null;
BufferedOutputStream outputStream = null;
try {
File fileXlsxPath = new File(filePath);
outputStream = new BufferedOutputStream(new FileOutputStream(fileXlsxPath));
workbook = new XSSFWorkbook();
workbook.createSheet("Sheet1");
workbook.write(outputStream);
} catch (Exception e) {
//e.printStackTrace();
} finally {
if (outputStream!=null) { try{outputStream.close(); }catch(Exception e) {}}
}
return workbook;
}
/**
* 判断row是否是空行
* @param row
* @return
*/
public boolean isEmptyRow(Row row) {
if(row == null || row.toString().isEmpty()){
return true;
}else{
Iterator<Cell> it = row.iterator();
boolean isEmpty = true;
while (it.hasNext()){
Cell cell = it.next();
if(cell.getCellTypeEnum() != CellType.BLANK){
isEmpty = false;
break;
}
}
return isEmpty;
}
}
public void updateTitle(String path, String fileZip,List<String> list) {
Workbook wb = null; BufferedOutputStream outputStream = null;
try {
wb = getWorkbook(wb, path, fileZip, fileZip.substring(fileZip.lastIndexOf(".")+1, fileZip.length()));
Row row = wb.getSheetAt(0).getRow(0);// 标题行
for (int i = row.getPhysicalNumberOfCells(); i < list.size(); i++) {
row.createCell(i, CellType.STRING).setCellValue(list.get(i));
}
outputStream = new BufferedOutputStream(new FileOutputStream(path+fileZip));
wb.write(outputStream);
outputStream.flush();
if (outputStream!=null) { try{outputStream.close(); }catch(Exception e) {}}
} catch (Exception e) {
addMsg("更新Excel标题时出错:"+e+"\r\n");
} finally {
if (wb!=null) { try{wb.close(); }catch(Exception e) {}}
}
}
}