Springboot 导出、导入csv文件(包含base64图片)

本文介绍了在Springboot中如何处理CSV文件,特别是当CSV中包含Base64编码的图片时需要注意的问题。针对数字超过12位变为科学计数法和Base64编码换行问题,提出了解决方案。推荐使用java.util.Base64进行Base64编码,并提供了相关的CSV工具类和文件处理方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

注意要点:

1、csv中会对数字超过12位时会变为科学计数,超过15位时其他位变为0.解决办法: 在数字后面加上 "\t"

2、图片转换为base64时,sun.misc.BASE64Encoder  方法 Base64一行不能超过76字符,超过会自动换行。在windows系统表现为\r\n ,linnux表现为: \n。

java.util.Base64 方法的加码不会生成换行符。建议推荐使用这个。

csv工具类:

package com.hikvision.modules.util;

/**
 * @Description csv导出类
 * @Author cx
 * @Date 2022/2/16 11:49
 * @since
 */
public interface CsvExportable {
    /**
     *
     * @methodName		: outputTitleLine
     * @description		: 输出标题行字符串
     * @return			: 标题行字符串
     *
     */
    public String outputCsvTitleLine();

    /**
     *
     * @methodName		: outputDataLine
     * @description		: 输出数据行
     * @return			: 符合CSV格式的数据行字符串
     *
     */
    public String outputCsvDataLine();

    /**
     *
     * @methodName		: CSVFormat
     * @description		: 将输入字符串格式化成CSV格式的字符串
     * @param input		: 输入字符串
     * @return			: 符合CSV格式的字符串
     *
     */
    public static String CSVFormat(String input) {
        boolean bFound = false;
        //如果值中含有逗号、换行符、制表符(Tab)、单引号,双引号,则需要用双引号括起来;
        //如果值中包含双引号,则需要用两个双引号来替换。
        //正则匹配:",'\"\r\n\t"
        bFound = input.matches("(.*)(,|'|\"|\r|\n|\t)(.*)");
        if (bFound) {
            //如果存在匹配字符
            //先将双引号替换为两个双引号
            String sTemp = input.replaceAll("\"", "\"\"");
            //然后,两端使用"字符
            sTemp ="\"" + sTemp + "\"";
            return sTemp;
        }
        return input;
    }
}
package com.hikvision.modules.util;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.List;

/**
 * @Description csv导出类
 * @Author cx
 * @Date 2022/2/16 11:48
 * @since
 */
public class CsvExportHandler<T extends CsvExportable>  {
    /**
     *
     * @methodName		: exportCsvFile
     * @description		: 导出CSV文件
     * @param rowDataList	: T类型对象列表
     * @param csvFilePath	: 输出的CSV文件路径
     * @throws Exception	: 异常发生时,抛出
     *
     */
    public File exportCsvFile(List<T> rowDataList, String csvFilePath)
            throws Exception{

        if (rowDataList.size() == 0) {
            //必须要有导出数据,否则创建标题列失败
            throw new Exception("无导出数据.");
        }

        //取得第一个对象
        T rowDataObj = rowDataList.get(0);

        //将数据写入csv格式文件
        File file = writeToCsv(rowDataList, rowDataObj, csvFilePath);
        return file;
    }

    /**
     *
     * @methodName		: writeToCsv
     * @description		: 将数据写入csv格式文件
     * @param dataList	: T类型对象列表
     * @param rowDataObj: T类型对象
     * @param filePath	: 输出的文件路径
     * @throws Exception	: 异常发生时,抛出
     *
     */
    private File writeToCsv(List<T> dataList, T rowDataObj, String filePath) throws Exception {
        FileOutputStream fos = null;
        BufferedOutputStream bos = null;
        String enter = "\r\n";
        String sLine;
        StringBuffer write ;
        File file = new File(filePath);
        fos = new FileOutputStream(file);
        bos = new BufferedOutputStream(fos);
        //标题行
        sLine = rowDataObj.outputCsvTitleLine();
        write = new StringBuffer();
        write.append(sLine);
        //加换行符
        write.append(enter);
        bos.write(write.toString().getBytes("GBK"));
        for (int i = 0; i < dataList.size(); i++) {
            write = new StringBuffer();
            T rowData = dataList.get(i);
            //输出CSV格式的数据行
            sLine = rowData.outputCsvDataLine();
            //写数据行
            write.append(sLine);
            //加换行符
            write.append(enter);
            bos.write(write.toString().getBytes("GBK"));
        }
        //刷新数据
        bos.flush();

        //关闭流
        bos.close();
        fos.close();
        return file;
    }
}

文件处理类:

package com.hikvision.modules.util;

import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import sun.misc.BASE64Encoder;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Objects;
import java.util.UUID;

/**
 * @Description 网络图片,下载转换为base64
 * @Author cx
 * @Date 2022/2/16 11:34
 * @since
 */
@Data
@Component
public class FileUtil {
    @Value("${faceAlarm.url.timeOut}")
    private int timeOut;

    /**
     * @param imgUrl
     * @Description: 根据url下载图片,转为base64
     * @Author: cx
     * @Date: 2022-02-16 11:35
     * @Return: String
     */
    public String pic2Base64(String imgUrl) {
        if(StringUtils.isEmpty(imgUrl)){
            return "";
        }
        URL url = null;
        InputStream is = null;
        ByteArrayOutputStream outStream = null;
        HttpURLConnection httpUrl = null;
        FileOutputStream fileOutputStream = null;
        try {
            url = new URL(imgUrl);
            httpUrl = (HttpURLConnection) url.openConnection();
            httpUrl.connect();
            httpUrl.getInputStream();
            httpUrl.setConnectTimeout(timeOut * 1000);
            is = httpUrl.getInputStream();

            outStream = new ByteArrayOutputStream();
            //创建一个Buffer字符串
            byte[] buffer = new byte[1024];
            //每次读取的字符串长度,如果为-1,代表全部读取完毕
            int len = 0;
            //使用一个输入流从buffer里把数据读取出来
            while ((len = is.read(buffer)) != -1) {
                //用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
                outStream.write(buffer, 0, len);
            }
            // 对字节数组Base64编码
            String picUrlStr = new BASE64Encoder().encode(outStream.toByteArray());
            File file = new File("E:\\pic" + File.separator + DateUtil.getCurrentDayString()
                     + "-" + UUID.randomUUID() + ".jpg");
            if (!file.exists()) {
                file.createNewFile();
            }
            fileOutputStream = new FileOutputStream(file);
            fileOutputStream.write(picUrlStr.getBytes());
            return picUrlStr;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (outStream != null) {
                try {
                    outStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (httpUrl != null) {
                httpUrl.disconnect();
            }
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}

调用方式:

CsvExportHandler<DemoDTO> csvExportHandler = new CsvExportHandler<>();
                File file = csvExportHandler.exportCsvFile(list, csvFilePath + "\\" + UUID.randomUUID() + "_" + System.currentTimeMillis() + ".csv");
                

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值