Java导出CSV文件
程序员文章站
2022-06-01 14:05:52
...
话不多说,直接上代码:
CsvExportUtil 类:
import org.apache.commons.lang3.StringUtils;
import sun.security.action.GetPropertyAction;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.security.AccessController;
import java.util.*;
import java.util.stream.Collectors;
/**
* <p> @Title CsvExportUtil
* <p> @Description Csv文件导出工具
*
* @author ACGkaka
* @date 2020/3/24 9:34
*/
public class CsvExportUtil {
private static final String LINE_SEPARATOR = AccessController.doPrivileged(new GetPropertyAction("line.separator"));
private static final String VALUE_SEPARATOR = ",";
/**
* 功能说明:获取UTF-8编码文本文件开头的BOM签名。
* BOM(Byte Order Mark),是UTF编码方案里用于标识编码的标准标记。例:接收者收到以EF BB BF开头的字节流,就知道是UTF-8编码。
* @return UTF-8编码文本文件开头的BOM签名
*/
public static String getBOM() {
byte[] bytes = {(byte)0xEF, (byte)0xBB, (byte)0xBF};
return new String(bytes);
}
/**
* 生成CVS文件
* @param exportData 源数据List
* @param outPutPath 文件路径
* @param fileName 文件名称
* @return
*/
public static synchronized File createCSVFile(List<List<String>> exportData, String outPutPath,
String fileName) throws IOException {
File file = new File(outPutPath);
if (!file.exists()) {
file.mkdirs();
}
//定义文件名格式并创建
File csvFile = new File(outPutPath + fileName + ".csv");
file.createNewFile();
try (
BufferedWriter csvFileOutputStream = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(csvFile), Charset.defaultCharset()), 1024)
) {
//写入前段字节流,防止乱码
csvFileOutputStream.write(getBOM());
// 写入文件内容
String content = exportData.stream().filter(Objects::nonNull).map(o ->
o.stream().filter(StringUtils::isNotEmpty).map(s -> {
s = s.replaceAll("\"", "\"\"");
return s.contains(VALUE_SEPARATOR) ? s : "\"" + s + "\"";
}).collect(Collectors.joining(VALUE_SEPARATOR))).collect(Collectors.joining(LINE_SEPARATOR));
csvFileOutputStream.write(content);
csvFileOutputStream.newLine();
csvFileOutputStream.flush();
}
return csvFile;
}
/**
* 生成并下载csv文件
* @param response
* @param exportData
* @param outPutPath
* @param fileName
* @throws IOException
*/
public static void exportDataFile(HttpServletResponse response,List exportData, String outPutPath,String fileName) throws IOException{
createCSVFile(exportData, outPutPath, fileName);
// 下载
try (InputStream in = new FileInputStream(outPutPath+fileName+".csv")) {
int len = 0;
byte[] buffer = new byte[1024];
OutputStream out = response.getOutputStream();
response.reset();
response.setContentType("application/csv;charset=UTF-8");
response.setHeader("Content-Disposition","attachment; filename=" + URLEncoder.encode(fileName+".csv", "UTF-8"));
response.setCharacterEncoding("UTF-8");
while ((len = in.read(buffer)) > 0) {
out.write(new byte[] { (byte) 0xEF, (byte) 0xBB, (byte) 0xBF });
out.write(buffer, 0, len);
}
out.close();
}
}
/**
* 测试数据
* @param args
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public static void main(String[] args) throws IOException {
List<List<String>> data = new ArrayList();
List<String> row = new ArrayList();
// 设置列名
row.add("第一列名称");
row.add("第二列名称");
row.add("第三列名称");
row.add("第四列名称");
data.add(row);
// 设置内容
row = new ArrayList();
row.add("11");
row.add("12");
row.add("13");
row.add("14");
data.add(row);
row = new ArrayList();
row.add("21");
row.add("22");
row.add("23");
row.add("24");
data.add(row);
//这个文件上传到路径,可以配置在数据库从数据库读取,这样方便一些!
String path = "E:/";
//文件名=生产的文件名称+时间戳
String fileName = "文件导出";
File file = CsvExportUtil.createCSVFile(data, path, fileName);
String fileName2 = file.getName();
System.out.println("文件名称:" + fileName2);
}
}
效果展示:
说明:
工具类主要是使用原始的Java IO流来操作。
借鉴于https://www.cnblogs.com/hanfengyeqiao/p/9471694.html,进行了部分的代码重构。
上一篇: 过度追求代码短小优雅有什么害处?