注意要点:
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");