easyexcel解析csv文件

背景:接着上一篇下载文件,从ftp下载到csv文件后,解析转换成想要的数据存储数据库,此处设计成用easyexcel读取csv中的数据,并转换成自己想要的格式,这里选easyexcel的原因就是因为简单,下面将逐步解释如何使用以及在使用中需要注意的事项。

引入依赖

        <!--easyExcel-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>3.1.2</version>
        </dependency>
        <!--zip操作-->
        <dependency>
            <groupId>org.apache.ant</groupId>
            <artifactId>ant</artifactId>
            <version>1.7.0</version>
        </dependency>

检查文件是否存在

listFiles是上一篇的方法
sourceOpt为真代表存在

List<String> files = sftpHelper.listFiles(sftpPathAll);
Optional<String> sourceOpt = files.stream().filter(f -> f.equals(fileName)).findFirst();

下载文件

downloadFile是上一篇的方法

sftpHelper.downloadFile(sftpPathAll, fileName, savePathAll);

解压文件

unZip方法是解压操作

package x.x.infra.util;

import java.io.*;
import java.nio.charset.Charset;
import java.util.Enumeration;

import lombok.extern.slf4j.Slf4j;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipOutputStream;

@Slf4j
public class ZipFileUtils {
    private static int bufferSize = 2048;

    /**
     * 解压到指定目录
     */
    public static void unZip(String zipPath, String descDir) throws IOException {
        unZip(new File(zipPath), descDir);
    }

    /**
     * 解压文件到指定目录
     */
    @SuppressWarnings("rawtypes")
    public static void unZip(File zipFile, String descDir) throws IOException {
        File pathFile = new File(descDir);
        if (!pathFile.exists()) {
            pathFile.mkdirs();
        }
        //解决zip文件中有中文目录或者中文文件
//        ZipFile zip = new ZipFile(zipFile, Charset.forName("GBK"));
        ZipFile zip = new ZipFile(zipFile);
        for (Enumeration entries = zip.getEntries(); entries.hasMoreElements(); ) {
            ZipEntry entry = (ZipEntry) entries.nextElement();
            String zipEntryName = entry.getName();
            InputStream in = zip.getInputStream(entry);
            String outPath = (descDir + zipEntryName).replaceAll("\\*", "/");
            //判断路径是否存在,不存在则创建文件路径
            File file = new File(outPath.substring(0, outPath.lastIndexOf('/')));
            if (!file.exists()) {
                file.mkdirs();
            }
            //判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压
            if (new File(outPath).isDirectory()) {
                continue;
            }
			log.info("解压文件路径:"+outPath);
            OutputStream out = new FileOutputStream(outPath);
            byte[] buf1 = new byte[1024];
            int len;
            while ((len = in.read(buf1)) > 0) {
                out.write(buf1, 0, len);
            }
            in.close();
            out.close();
        }
    }

    /**
     * 压缩
     * @param srcFileOrDir 原文件或文件夹
     * @param destZipFilePath 输出到的目标路径,默认zip文件为原文件或文件夹名称
     */
    public static boolean zip(String srcFileOrDir, String destZipFilePath){
        File file = new File(srcFileOrDir);
        if(!file.exists()){
            return false;
        }

        String destZipFileName = file.getName();

        return zip(srcFileOrDir, destZipFilePath, destZipFileName);
    }

    /**
     * 压缩
     * @param srcFileOrDir 原文件或文件夹
     * @param destZipFilePath 输出到的目标路径
     * @param destZipFileName 生成的zip文件名称
     */
    public static boolean zip(String srcFileOrDir, String destZipFilePath, String destZipFileName){
        File file = new File(srcFileOrDir);
        if(!file.exists()){
//            logger.info("原文件或文件夹不存在。");
            return false;
        }

        if(!destZipFilePath.endsWith(File.separator)){
            destZipFilePath += File.separator;
        }

        File destZipFileParentDir = new File(destZipFilePath);
        if(!destZipFileParentDir.exists()){
            destZipFileParentDir.mkdirs();
        }

        if(!destZipFileName.endsWith(".zip")&&!destZipFileName.endsWith(".ZIP")){
            destZipFileName += ".zip";
        }

        boolean zipResult = false;
        if(file.isFile()){
            zipResult = zipFile(srcFileOrDir, destZipFilePath, destZipFileName);
        }else if(file.isDirectory()){
            zipResult = zipDir(srcFileOrDir, destZipFilePath, destZipFileName);
        }

//        logger.info("["+srcFileOrDir+"]-->["+destZipFilePath + destZipFileName+"]压缩结果:["+zipResult+"]");

        return zipResult;
    }



    private static boolean zipFile(String srcFileName, String destZipFilePath, String destZipFileName){
        boolean zipResult = false;
        File srcFile = new File(srcFileName);

        ZipOutputStream zipOutputStream = null;
        try {
            zipOutputStream = new ZipOutputStream(new FileOutputStream(destZipFilePath + destZipFileName));
            zipOutputStream.setEncoding(System.getProperty("sun.jnu.encoding"));

            String fileName = srcFile.getName();
            ZipEntry entry = new ZipEntry(fileName);

            BufferedInputStream bis = null;
            try {
                zipOutputStream.putNextEntry(entry);
                bis = new BufferedInputStream(new FileInputStream(srcFile));

                byte[] buf = new byte[bufferSize];
                int len;
                while ((len = bis.read(buf)) >= 0) {
                    zipOutputStream.flush();
                    zipOutputStream.write(buf, 0, len);
                }
                zipResult = true;
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if(zipOutputStream!=null){
                        zipOutputStream.closeEntry();
                    }

                    if(bis!=null){
                        bis.close();
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                if(zipOutputStream!=null){
                    zipOutputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return zipResult;
    }

    private static boolean zipDir(String srcDir, String destZipFilePath, String destZipFileName){
        boolean zipResult = false;
        if(!srcDir.endsWith(File.separator)){
            srcDir += File.separator;
        }
        File srcFile = new File(srcDir);
        File[] files = srcFile.listFiles();

        ZipOutputStream zipOutputStream = null;
        try {
            zipOutputStream = new ZipOutputStream(new FileOutputStream(destZipFilePath + destZipFileName));
            zipOutputStream.setEncoding(System.getProperty("sun.jnu.encoding"));
            if(files!=null&&files.length>0){
                for(File f :files){
                    compressFiles(f, f.getParent() ,zipOutputStream);
                }
            }
            zipResult = true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                if(zipOutputStream!=null){
                    zipOutputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return zipResult;
    }
    private static void compressFiles(File file, String basePath, ZipOutputStream stream){
        if(file==null||stream==null){
            return;
        }
        if(file.isDirectory()){
            ZipEntry entry = new ZipEntry(getEntryPath(file,basePath) + File.separator);
            try {
                stream.putNextEntry(entry);
            } catch (IOException e) {
                e.printStackTrace();
            }

            File[] files = file.listFiles();
            if(files!=null&&files.length>0){
                for(File f :files){
                    compressFiles(f, basePath, stream);
                }
            }
        }else{
            String fileName = getEntryPath(file, basePath);
            ZipEntry entry = new ZipEntry(fileName);

            BufferedInputStream bis = null;
            try {
                stream.putNextEntry(entry);
                bis = new BufferedInputStream(new FileInputStream(file));

                byte[] buf = new byte[bufferSize];
                int len;
                while ((len = bis.read(buf)) >= 0) {
                    stream.flush();
                    stream.write(buf, 0, len);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if(stream!=null){
                        stream.closeEntry();
                    }

                    if(bis!=null){
                        bis.close();
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private static String getEntryPath(File file, String basePath){
        String path = file.getPath().substring(basePath.length() + 1);
        return path;
    }
}

定义非数据库对象

复制一份已有的数据库对象,加个VO后缀代表是非数据库对象,修改此VO结尾的对象的字段属性全部为string,因为在easyexcel转换对象映射的时候会默认转成string类型。@ExcelProperty此注解定义和csv文件列的关系。这里注意那些没用的属性不要出现在此映射类中。

@Getter
@Setter
@JsonInclude(value = JsonInclude.Include.NON_NULL)
public class GlDetailLineItfVo {

    @ExcelProperty(index = 0)
    private String name;
}

读取文件封装成想要的对象

invoke此方法第一个形参是读取到csv文件中的数据,在这里可以操作那些对象映射不上的数据转换,比如日期类型BigDecimal类型等,然后存入一个list中,返回出来给外面的方法用。charset设置中文乱码问题,excelType设置读取文件格式,sheet设置读取第几个页,headRowNumber设置从第几行开始读默认是第二行。

public List<Itf> getObjFromCsv(Map<String, String> map) {
        Optional.ofNullable(map.get("filePath")).orElseThrow(() -> new CommonException("文件路径不能为空"));
        File file = new File(map.get("filePath"));
        InputStream is = null;
        List<Itf> itfList = new ArrayList<>();
        try {
            //获取输入流
            is = new FileInputStream(file);
            EasyExcel.read(is, itfVo.class, new ReadListener<itfVo>() {
                        @Override
                        public void invoke(itfVo data, AnalysisContext context) {
                            Integer row = context.readRowHolder().getRowIndex();
                            System.out.println("第几行数据:"+row);
                            //把解析到的每一行数据都存入list中
                            Itf itf= new Itf();
                            BeanUtils.copyProperties(data,itf);
                            //手动转换对象不一致的属性
                            } catch (ParseException e) {
                                throw new RuntimeException(e);
                            }
                            itfList .add(itf);
                        }
                        @Override
                        public void doAfterAllAnalysed(AnalysisContext context) {
                            System.out.println("最后一次走这里");
                            //这里可以写操作数据库,我没写,我的操作数据库是另外一个方法
                        }
                    }).charset(Charset.forName("GBK"))//中文乱码
                    .excelType(ExcelTypeEnum.CSV)//文件格式
                    .sheet(0)//读取第一个sheet
                    .headRowNumber(1)//从数据的第2行开始读
                    .doRead();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                is.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return itfList ;
    }

至此下载文件,解压,解析已经完成

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在使用EasyExcel导出CSV文件时,表头不生效的原因可能有多种。以下是一些可能的原因和解决方案: 1. 检查是否正确设置了文件格式为CSV 在使用EasyExcel导出CSV文件时,需要设置文件格式为CSV。您可以在代码中使用以下方法设置文件格式: ```java response.setContentType("application/csv;charset=utf-8"); response.setCharacterEncoding("UTF-8"); response.setHeader("Content-disposition", "attachment;filename=" + fileName); ``` 其中,`response`表示HTTP响应对象,`fileName`表示导出文件文件名。 2. 检查是否正确设置了表头 在使用EasyExcel导出CSV文件时,需要正确设置表头。您可以在代码中使用以下方法设置表头: ```java List<List<String>> head = new ArrayList<List<String>>(); // 设置表头 List<String> header0 = new ArrayList<String>(); header0.add("姓名"); header0.add("年龄"); head.add(header0); ``` 在上面的代码中,我们设置了表头为`姓名`和`年龄`两列。您可以根据需要设置表头列数和列名。 3. 检查是否正确使用EasyExcel导出CSV文件 EasyExcelCSV导出功能与Excel导出功能略有不同。您可以参考以下代码示例正确使用EasyExcel导出CSV文件: ```java // 创建写入文件对象 File file = new File("test.csv"); // 写入文件 EasyExcel.write(file).head(head).sheet().doWrite(data); ``` 在上面的代码中,我们先创建了一个文件对象`file`,然后使用EasyExcel的写入功能将数据写入文件中。`head`表示表头,`data`表示数据列表。 如果您仍然无法解决问题,可以将您的代码片段和具体报错信息提供给EasyExcel开发者或社区论坛,获取更好的帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值