赞
踩
感谢写代码的时候遇到的所有大恩人!磕头了磕头了!
咚!咚!咚!
昨天晚上接了个活。
每个月的月初需要把上个月的物流提单大包数和对应的ID上传到特定的表格中...
做法是先在在线表格取得提单号,根据提单号从邮件里找到对应提单的预报邮件,下载一个压缩包,压缩包里有一个Excel表格,表格里有几万个大包号,需要手动把大包号去重,把大包数量和大包ID提取出来塞到在线表格里。
这是其中一个表格,一共150个
一个不熟练的人估计需要做一上午。
想了下,之前弄过POI,可以用POI把表格数据提出来,去重,最后输出出来,再往在线表格里塞,这样能节省几个小时。
嘿嘿....开动
首先:从邮件里搜索到下载这一步只能手工搞,我可以把压缩包重命名成提单号,解压缩出来带有提单号的目录,目录里只有一个Excel文件,用Java把Excel文件名改成提单号。遍历每个Excel文件,用POI把数据去重输出,输出数据数量和数据内容。
说干就干。
首先获取整个文件夹的文件名称并赋给文件夹内的文件,我参考了虫卅blog中的一部分代码
【java】如何获取整个文件夹的文件名称_java获取文件名称_虫卅的博客-CSDN博客
- package com;
-
- import java.io.File;
-
- public class FileDemo {
-
- private static String filepath="D:\\test\\2023-05-10";
-
- public static void getfileName(String filepath) {
-
- //获取目录下所有文件的名字(不包括文件夹)
- File f3 = new File(filepath);
- File[] files = f3.listFiles();
- for (File fi : files){
- if (fi.isFile()){
- System.out.println(fi.getName());
- }
- }
-
- }
- }
-
遍历出来xslx文件之后,使用file.renameTo(new File(filename));方法重命名,但是失败了,翻了不少博客又看了不少文章也找不出个所以然,倒是删除文件没问题。后来看了另外一位朋友的博客决定曲线救国,复制文件改名。
大概意思就是引用一个FileUtils类,通过这个类去把文件复制。我找了几个博客看了下
Java常用类(三):FileUtils类_出处不详,经久不息的博客-CSDN博客
- public class FileDemo {
-
- private static String filepath="D:\\test\\2023-05-10";
- private static String xlsxdirName;
- private static String xlsxpath;
- ....
- public static void getfileName(String filepath) throws IOException {
- //获取目录下所有文件的名字(不包括文件夹)
- File f3 = new File(filepath);
- File[] files = f3.listFiles();
- for (File fi : files){
- if (fi.isFile()){
- System.out.println(fi.getName());
- //fi.renameTo(new File(xlsxdirName+".xlsx"));
- FileUtils.copyFile(fi,new File(xlsxdirName + ".xlsx"));
- //FileUtils.delete(fi);
- }
- }
- }
- }
运行了下,没反应...找了半天才发现,文件复制+重命名成功了,但是复制到了项目目录下...
行吧...
下面搞遍历,遍历所有目录。
- public static void readfile_(String filepath) throws FileNotFoundException, IOException {
- File file = new File(filepath);
- String[] list=file.list();
- for(int i=0;i<list.length;i++){
- if(file.isDirectory()){
- System.out.println(list[i]);
- xlsxdirName=list[i];
- xlsxpath=filepath + "\\" + xlsxdirName;
- getfileName(xlsxpath);
- }
- }
- }
很轻松。写个main函数。
整个目录中所有的表格名都被改成提单号了
- package com.cecz;
-
-
- import org.apache.commons.io.FileUtils;
-
- import java.io.File;
- import java.io.FileNotFoundException;
- import java.io.IOException;
-
- /**
- * 目的:输入目录,将目录中所有的文件复制到另外一个目录并将其重命名为目录名
- * filepath:目录路径
- * xlsxdirName:目录里所有目录名称
- * xlsxpath:表格路径
- * */
-
- public class FileDemo {
-
- private static String filepath="D:\\test\\2023-05-10";
- private static String xlsxdirName;
- private static String xlsxpath;
-
- public static void main(String[] args) throws IOException {
- readfile_(filepath);
- }
- public static void readfile_(String filepath) throws FileNotFoundException, IOException {
- File file = new File(filepath);
- String[] list=file.list();
- for(int i=0;i<list.length;i++){
- if(file.isDirectory()){
- System.out.println(list[i]);
- xlsxdirName=list[i];
- xlsxpath=filepath + "\\" + xlsxdirName;
- getfileName(xlsxpath);
- }
- }
- }
- //get目录下的name并将其重命名→输出文件夹:D:\dev-project\IdeaProjects\cecz-excel
- public static void getfileName(String filepath) throws IOException {
- //获取目录下所有文件的名字(不包括文件夹)
- File f3 = new File(filepath);
- File[] files = f3.listFiles();
- for (File fi : files){
- if (fi.isFile()){
- System.out.println(fi.getName());
- //fi.renameTo(new File(xlsxdirName+".xlsx"));
- FileUtils.copyFile(fi,new File(xlsxdirName + ".xlsx"));
- //FileUtils.delete(fi);
- }
- }
- }
- }
-
下面开始搞POI
POI比较轻松,不过长时间不做这个有点记不清了,就去狂神那里看了一i眼。
通过FirstTalent的博客知道了如何获取表格里的总行数
利用poi获取导入的Excel表格一共有多少行数据!!!_poi获取excel行数_FirstTalent的博客-CSDN博客
需要把每行的大包数找出来进行,删除重复的数据
思路是先初始化一个静态数组和一个int类型的count,每遍历一行数据就和数组里的数据进行比对,如果数组里没有的话就直接add进并且count++。遍历完所有行之后遍历数组并取得数组长度
想了一下这有没有什么类库能实现...一拍脑瓜
ArrayList搞得定啊!
找了一篇博客
如何在Java中将String值与String类型的ArrayList进行比较? | 码农家园
list.contains()方法,舒服了!
- package com.cpp;
-
-
- 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 org.junit.jupiter.api.Test;
-
- import java.io.*;
- import java.util.ArrayList;
-
- public class ExcelReadTest {
-
- public static int count=0;
-
- public static ArrayList<String> list=new ArrayList<>();
-
- public static String path="D:\\dev-project\\IdeaProjects\\cecz-excel";
-
-
- public ExcelReadTest() throws FileNotFoundException {
- }
-
- //
- public static void main(String[] args) throws IOException {
- //将Java程序的输出结果写到txt文件
- PrintStream ps = new PrintStream("D:\\log.txt");
- System.setOut(ps);//sout出的都进log.txt中
- //遍历所有文件执行testRead07
- File allFiles = new File(path);
- String[] list=allFiles.list();
- for(int i=0;i<list.length;i++){
- if(allFiles.isDirectory()){
- if(list[i].endsWith(".xlsx")){
- System.out.println("================"+list[i]+"=====================");
- testRead07(list[i]);
- }
- }
- }
- }
- public static void testRead07(String fileName) throws IOException {
- //读取excel文件
- FileInputStream fileInputStream = new FileInputStream(path+"\\"+fileName);
- Workbook workbook = new XSSFWorkbook(fileInputStream);
- Sheet sheet = workbook.getSheetAt(0);
- // Row row = sheet.getRow(1);
- // Cell cell = row.getCell(1);
- //获取行数
- int physicalNumberOfRows = sheet.getPhysicalNumberOfRows();
- //输出行数到*********控制台
- System.out.println("行数="+physicalNumberOfRows);
- //遍历行,做对比
- for(int i=1;i<physicalNumberOfRows;i++){
- Row row = sheet.getRow(i);
- Cell cell = row.getCell(1);
- // System.out.println(cell.getStringCellValue());
- compare(cell.getStringCellValue());
- }
- //完成之后返回行数和list中的数据
- System.out.println("行数:"+list.size());
- for (String str:list) {
- //输出比对好的list数据到*******控制台
- System.out.println(str);
- }
- //清除list并count归零
- list.clear();
- count=0;
- }
- /**
- * 对比num和数组中的数据,
- * 如果数组里没有num,则放入,count+1。
- * 如果有,则不防暑
- * */
- public static void compare(String num){
- if(!list.contains(num)){
- list.add(num);
- count++;
- }
- }
- }
接着遍历目录里所有的文件,并把数据打印在txt文档里。
感谢太閤秀吉的文章
java输出结果到txt_将Java程序的输出结果写到txt文件中的方法_太閤秀吉的博客-CSDN博客
齐活,一个月干一天的工作俩小时搞定了...
下面开始考虑怎么把list里的数据塞进在线表格里的Cell里....
有点麻烦似乎...
更新于2023年8月8日
其实一点都不麻烦,只要找到了对应方法
我首先看了下如何实现单元格内容换行
这篇文章解决了我的问题
java POI实现Excel单元格内容换行_java实现excel换行_congcongxianshen的博客-CSDN博客
试了一下插入失败,报错空指针,网上说是需要先判断Cell是否为空,再使用对应方法..
写上了,试了以下,仍然写入失败,程序直接退出,插入失败。
不过查找算是查找到了,去网上查了一下,哦原来是我没写输出流关闭流...
POI向Excel中写入数据及追加数据 - Ethon - 博客园 (cnblogs.com)
三个月没碰咋代码差点忘了
加了输出流之后运行直接报错Package should contain a content type part [M1.13],还是插入失败
打开Excel的时候发现文件坏了
网上查了一篇文章,原因是我输出流初始化的语句卸载了输入流初始化下边,这容易报错。原因不知道,算了,写在最下边。
POI操作EXCEL,追加或覆盖数据,输入输出流注意事项,jar包的选择 - allMayMight - 博客园 (cnblogs.com)
代码写完了,执行,还是报错,我在输出流附近打了个桩,NM根本没执行这段语句啊!
我把该犯的错误都犯了,能解决的都解决了!问题出在哪里了呢?
- private static void output(String caselsh) throws IOException {
- System.out.println(caselsh);
- boolean flag=false;
- FileInputStream fileInputStream = new FileInputStream(outputPath);
- FileOutputStream fileOutputStream = null;
- XSSFWorkbook workbook = new XSSFWorkbook(fileInputStream);
- //设置自动换行样式
- XSSFCellStyle cellStyle = workbook.createCellStyle();
- cellStyle.setWrapText(true);
- //处理list
- String content = String.join("\n", list);
- XSSFSheet sheet = workbook.getSheetAt(0);
- int rows = sheet.getPhysicalNumberOfRows();//获取当前文件行数
- for(int i=2;i<rows;i++){
- XSSFRow row = sheet.getRow(i);
- XSSFCell cell = row.getCell(1);
- if(cell.getStringCellValue().equals(caselsh)){
- System.out.println("找到了,在第"+i+"行!");
- //XSSFCell cell1 = sheet.getRow(i).createCell(7);
- XSSFCell cell1 = row.getCell(6);
- if(cell1==null){
- cell1=row.createCell(6);
- cell1.setCellValue(content);
- cell1.setCellStyle(cellStyle);
- }else{
- cell1=row.getCell(6);
- cell1.setCellValue(content);
- cell1.setCellStyle(cellStyle);
- }
- //cell1.setCellValue(1);
- //cell1.setCellStyle(cellStyle);
- flag=true;
- return;//结束本循环
- }
- }
- if(flag==false){
- //当循环结束,flag为false,表示本excel里没有此提单号(这他妈不正常),在底部新增一个一行一会再处理
- System.out.println("没有!");
- }
-
- fileOutputStream=new FileOutputStream(outputPath);
- try{
- System.out.println("save~~~~~");
- fileOutputStream.flush();
- workbook.write(fileOutputStream);
- fileOutputStream.close();
- }catch (Exception e){
- e.printStackTrace();
- }
- }
找了一个小时,终于找到了,循环跳出写了个return,应该写break。
写runtrn不仅跳出循环,还跳出当前方法,直接下边不执行了,当然没法保存了!
写break只跳出循环。
这种二笔错误竟然犯了...自己去墙边罚站了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。