Excel的读取跟写入
对一个目录下多个文件下,文件夹下的文件夹里的Excel文件读取,并写入
目录结构如:
- 总文件
- 材料
- 案卷1.xlsx
- 案卷2.xlsx
- 案卷3.xlsx
- …
- 信息
- 案卷1.xlsx
- 案卷2.xlsx
- 案卷3.xlsx
- …
- 电学
- 案卷1.xlsx
- 案卷2.xlsx
- 案卷3.xlsx
- …
- 医药
- 案卷1.xlsx
- 案卷2.xlsx
- 案卷3.xlsx
- …
- …
读取.xlsx文件中某一列,获取值后,在其他地方查到相关信息,补充到该行的其他的cell里,再写入文件
一、遍历循环目录文件,取到所有.xlsx文件
maven引入poi:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.10-FINAL</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.10-FINAL</version>
</dependency>
代码
public class FileU {
private static List<File> filelist =new ArrayList<>();
public static List<File> getFileList(String strPath) {
File dir = new File(strPath);
File[] files = dir.listFiles(); // 该文件目录下文件全部放入数组
if (files != null) {
for (int i = 0; i < files.length; i++) {
String fileName = files[i].getName();
if (files[i].isDirectory()) { // 判断是文件还是文件夹
getFileList(files[i].getAbsolutePath()); // 获取文件绝对路径
} else if (fileName.endsWith("xlsx")) { // 判断文件名是否以.xlsx结尾
String strFileName = files[i].getAbsolutePath();
System.out.println("---" + strFileName);
filelist.add(files[i]);
} else {
continue;
}
}
}
return filelist;
}
二、读取Excel,并组装数据,再写入Excel
1.拿到一个文件File
2.给sheet(0)页的第一行,新增内容加上标题
3.取sheet(0)页的第2行到最后一行,固定列的值,查询别处后获得该行该列cell字段的其他信息,新建该行cell(9)、cell(10)、cell(11),并赋值,所有行完成后,新建outputstream,将outputstream写入sheet的 workBook,最后判断并关闭各种流
代码
public class CombineData {
public void doCombine(File file) throws IOException, TRSException {
InputStream inputStream = new FileInputStream(file);
XSSFWorkbook wb = null;
wb = new XSSFWorkbook(inputStream);
XSSFSheet sheet = wb.getSheetAt(0);
sheet.getRow(0).createCell(9).setCellValue("IPC_MAIN");
sheet.getRow(0).createCell(10).setCellValue("GK_IC");
sheet.getRow(0).createCell(11).setCellValue("GK_TI");
for (int i =1;i<=sheet.getLastRowNum();i++){
Row row = sheet.getRow(i);
String an = row.getCell(5).getStringCellValue().trim();
TrsU trsU = new TrsU();
Entry en = trsU.getInfo(an);
row.createCell(9).setCellValue(en.getIPC_MAIN());
row.createCell(10).setCellValue(en.getGK_IC());
row.createCell(11).setCellValue(en.getGK_TI());
}
OutputStream outputStream = new FileOutputStream(file);
wb.write(outputStream);
if(outputStream != null){
outputStream.flush();
outputStream.close();
}
if(inputStream!=null){
inputStream.close();
}
System.out.println("已完成:"+file.getAbsolutePath());
}
}
三、准备工作做好后,整体调用
1.模版模式
定义一个抽象类,类中定义protected abstract 的init、process、close方法,这样子类继承后,并继承相应的方法,再定义一个public 方法,编辑一个调用执行顺序;
- 有抽象方法的类一定是抽象类,该类要由abstract修饰
- 抽象类中不一定有抽象方法
- public、final、protected、private:
public:所有位置都可以访问
fianl:默认为fianl友好型,默认状态,同包下都可以访问
protected:子类可以访问
private:只有类内部可以访问
代码
public abstract class Model {
protected abstract void init();
protected abstract void process();
protected abstract void close();
public void model(){
init();
process();
close();
}
}
2.子类继承模版方法
这里用到了JDK1.8的新特性,分流stream,根据计算机cup核数new线程
标题
public class MainProcess extends Model {
static List<File> filelist;
@Override
protected void init() {
System.out.println("start time :"+new Date());
filelist =FileU.getFileList("E:\\总文件夹");
}
@Override
protected void process() {
Stream<File> stream = filelist.parallelStream();
System.out.println("total:"+filelist.size());
CombineData com = new CombineData();
stream.forEach(file -> {
try {
com.doCombine(file);
} catch (IOException e) {
e.printStackTrace();
System.out.println("有问题:"+file.getAbsolutePath());
} catch (TRSException e) {
e.printStackTrace();
System.out.println("有问题:"+file.getAbsolutePath());
}
});
System.out.println("end time :"+new Date());
}
@Override
protected void close() {
ConnectionPool.close();
}
}
小结
1.写函数方法,第一步一定要判断参数的合理性
2.读写Excel的时候,XSSFWorkbook wb =new XSSFWorkbook,补全完数据之后,要new outputStream实现类,将outputStream写入到wb中,不重写写入wb中就等于没操作,在Excel中没有体现
3.递归目录的时候切记不能直接return ,那样就读完一个文件,return了就不继续循环了
if (files[i].isDirectory()) { // 判断是文件还是文件夹
getFileList(files[i].getAbsolutePath()); // 获取文件绝对路径
// return getFileList(files[i].getAbsolutePath()); //错误的写法,只读完一个文件
}
4.记得开启的流相关的要关闭
- 流操作要关闭流,关闭之前要判断 是否为null,不为null关闭
- 结果集也要关闭
- 数据库连接要检查关闭
- 要是有sql的 预处理,prepareStament,也要关闭