import org.apache.commons.io.ByteOrderMark;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* CSV工具类
*/
public class CSVUtil {
private static final Logger logger = LoggerFactory.getLogger(CSVUtil.class);
/**
* 换列符
*/
private static final String LF = ",";
/**
* 换行符
*/
private static final String HF = "\r\n";
/**
* 写CSV并转换为字节流
*
* @param columns 表头
* @param fields 属性
* @param cellList 数据
* @return
*/
public static byte[] writeDataAfterToBytes(String[] columns, String[] fields, List<Object> cellList) {
byte[] bytes = new byte[0];
ByteArrayOutputStream byteArrayOutputStream = null;
OutputStreamWriter outputStreamWriter = null;
BufferedWriter bufferedWriter = null;
try {
byteArrayOutputStream = new ByteArrayOutputStream();
outputStreamWriter = new OutputStreamWriter(byteArrayOutputStream, StandardCharsets.UTF_8);
bufferedWriter = new BufferedWriter(outputStreamWriter);
//excel文件需要通过文件头的bom来识别编码,而CSV文件格式不自带bom,所以写文件时,需要先写入bom头,否则excel打开乱码
bufferedWriter.write(new String(ByteOrderMark.UTF_8.getBytes()));
//写表头
StringBuilder sb = new StringBuilder();
String tableHeader = String.join(LF, columns);
sb.append(tableHeader + HF);
for (Object obj : cellList) {
Map<String, Object> map = obj instanceof Map ? (Map<String, Object>) obj : MapUtil.transBean2Map(obj);
for (int i = 0; i < fields.length; i++) {
Object value = map.get(fields[i]);
sb.append(formatValue(value) + LF);
}
sb.append(HF);
}
bufferedWriter.write(sb.toString());
bufferedWriter.flush();
//把输出流转换字节流
bytes = byteArrayOutputStream.toString(StandardCharsets.UTF_8.name()).getBytes();
return bytes;
} catch (IOException e) {
logger.error("writeDataAfterToBytes IOException:{}", e.getMessage(), e);
} finally {
try {
if (bufferedWriter != null) {
bufferedWriter.close();
}
if (outputStreamWriter != null) {
outputStreamWriter.close();
}
if (byteArrayOutputStream != null) {
byteArrayOutputStream.close();
}
} catch (IOException e) {
logger.error("iostream close IOException:{}", e.getMessage(), e);
}
}
return bytes;
}
/**
* 生成CSV文件到指定目录
*
* @param columns 表头
* @param fields 数据集对应字段名
* @param cellList 数据集
* @param filePath 生成路径及文件名
*/
public static void writeDataAfterToFile(String[] columns, String[] fields, List<Object> cellList, String filePath) {
byte[] bytes = new byte[0];
BufferedWriter bufferedWriter = null;
try {
bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filePath, true), StandardCharsets.UTF_8));
//excel文件需要通过文件头的bom来识别编码,而CSV文件格式不自带bom,所以写文件时,需要先写入bom头,否则excel打开乱码
bufferedWriter.write(new String(ByteOrderMark.UTF_8.getBytes()));
//写表头
StringBuilder sb = new StringBuilder();
String tableHeader = String.join(LF, columns);
sb.append(tableHeader + HF);
for (Object obj : cellList) {
Map<String, Object> map = obj instanceof Map ? (Map<String, Object>) obj : MapUtil.transBean2Map(obj);
for (int i = 0; i < fields.length; i++) {
Object value = map.get(fields[i]);
sb.append(formatValue(value) + LF);
}
sb.append(HF);
}
bufferedWriter.write(sb.toString());
bufferedWriter.flush();
} catch (IOException e) {
logger.error("writeDataAfterToBytes IOException:{}", e.getMessage(), e);
} finally {
try {
if (bufferedWriter != null) {
bufferedWriter.close();
}
} catch (IOException e) {
logger.error("iostream close IOException:{}", e.getMessage(), e);
}
}
}
/**
* 格式化数据
*
* @param cellVal 内容
*/
public static String formatValue(Object cellVal) {
String value = null;
if (cellVal == null || String.class.equals(cellVal.getClass())) {
value = StringUtil.isHref(cellVal);
} else if (Integer.class.equals(cellVal.getClass()) || int.class.equals(cellVal.getClass())
|| Long.class.equals(cellVal.getClass()) || long.class.equals(cellVal.getClass())
|| Double.class.equals(cellVal.getClass()) || double.class.equals(cellVal.getClass())
|| Float.class.equals(cellVal.getClass()) || float.class.equals(cellVal.getClass())
|| BigDecimal.class.equals(cellVal.getClass())) {
value = cellVal.toString();
} else if (Date.class.equals(cellVal.getClass())) {
value = DateUtil.format((Date) cellVal, com.zjm.util.DateUtil.DATETIME_PATTERN);
} else if (Timestamp.class.equals(cellVal.getClass())) {
value = DateUtil.format((Timestamp) cellVal, com.zjm.util.DateUtil.DATETIME_PATTERN);
} else {
value = StringUtil.isNull(cellVal);
}
return value;
}
/**
* 设置下载响应
*
* @param fileName
* @param bytes
* @param response
*/
public static void responseSetProperties(String fileName, byte[] bytes, HttpServletResponse response) {
try {
fileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.name());
response.setContentType("application/csv");
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
response.setHeader("Pragma", "public");
response.setHeader("Cache-Control", "max-age=30");
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
OutputStream outputStream = response.getOutputStream();
outputStream.write(bytes);
outputStream.flush();
} catch (IOException e) {
logger.error("iostream error:{}", e.getMessage(), e);
}
}
}
CSV工具类
最新推荐文章于 2024-05-29 08:28:42 发布