业务开放过程中, 经常需要使用到csv导入导出的功能,我们可以使用opencsv库封装工具类。
pom引入:
<!-- csv--> <dependency> <groupId>com.opencsv</groupId> <artifactId>opencsv</artifactId> <version>5.2</version> </dependency>
工具类封装:
package com.digquant.util; import com.opencsv.CSVWriter; import com.opencsv.bean.StatefulBeanToCsv; import com.opencsv.bean.StatefulBeanToCsvBuilder; import com.opencsv.exceptions.CsvDataTypeMismatchException; import com.opencsv.exceptions.CsvRequiredFieldEmptyException; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.util.List; @Slf4j public class CsvUtil<T> { public void generateCsvFile(List<T> exportResults, String fileName, String[] header) throws IOException, CsvDataTypeMismatchException, CsvRequiredFieldEmptyException { Writer writer = new FileWriter(fileName); //utf-8 bom writer.write(new String(new byte[] { (byte) 0xEF, (byte) 0xBB,(byte) 0xBF })); // 写表头 CSVWriter csvWriter = new CSVWriter(writer, CSVWriter.DEFAULT_SEPARATOR, CSVWriter.NO_QUOTE_CHARACTER, CSVWriter.NO_ESCAPE_CHARACTER, CSVWriter.DEFAULT_LINE_END); csvWriter.writeNext(header); //写内容 StatefulBeanToCsv beanToCsv = new StatefulBeanToCsvBuilder(writer).build(); beanToCsv.write(exportResults); csvWriter.close(); writer.close(); } /** * 读取csv文件流返回前端下载 * @param fileName * @param response * @throws UnsupportedEncodingException */ public void readCsvFileStream(String fileName, HttpServletResponse response) throws UnsupportedEncodingException { String myFileName = new String(fileName.getBytes("utf-8"), "gbk"); File file = new File(myFileName); if (file.exists()) { response.setContentType("application/force-download");// 设置强制下载不打开 response.addHeader("Content-Disposition", "attachment;fileName=" + myFileName);// 设置文件名 byte[] buffer = new byte[1024]; FileInputStream fis = null; BufferedInputStream bis = null; try { fis = new FileInputStream(file); bis = new BufferedInputStream(fis); OutputStream os = response.getOutputStream(); int i = bis.read(buffer); while (i != -1) { os.write(buffer, 0, i); i = bis.read(buffer); } } catch (Exception e) { e.printStackTrace(); } finally { if (bis != null) { try { bis.close(); } catch (IOException e) { e.printStackTrace(); } } if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } } if(file.delete()){ log.error(file.getName() + " 文件已被删除!"); }else{ log.error("文件删除失败!"); } } }
在使用csv过程中, 常见的问题有 csv的中文乱码问题,在写csv文件时,微软的csv采用的utf-8 bom的编码格式,因此我们可以在文件头3字节写入utf-8 bom说明文件格式
//utf-8 bom writer.write(new String(new byte[] { (byte) 0xEF, (byte) 0xBB,(byte) 0xBF }));
说到编码集,我们同样可以读取文件的前三个字节,关于一下代码,你是否有些许问题呢?评论交流吧
public static String GetFileCharset(InputStream ins) { BufferedInputStream bin = new BufferedInputStream(ins); int p = 0; try { p = (bin.read() << 8) + bin.read(); } catch (IOException e) { e.printStackTrace(); return ""; } String code = null; switch (p) { case 0xefbb: code = "UTF-8"; break; case 0xfffe: code = "Unicode"; break; case 0xfeff: code = "UTF-16BE"; break; default: code = "GBK"; } return code; }