前提: 1.要进行百万级数据的导出 2.导出格式为csv文件
首先需要导入依赖
<dependency>
<groupId>net.sourceforge.javacsv</groupId>
<artifactId>javacsv</artifactId>
<version>2.0</version>
</dependency>
Controller:
@RequestMapping(value = "/downloadFile", method = RequestMethod.POST, produces ="application/x-www-form-urlencoded;charset=UTF-8")
public void downloadFile( HttpServletResponse response, Vo vo) {
log.info("start download , info:{}", vo);
long start = System.currentTimeMillis();
File tempFile = Service.download(vo);
CsvUtil.outCsvStream(response, tempFile, ExportInfoConstant.PROPERTY_NAME);
CsvUtil.deleteFile(tempFile);
log.info("Download Over , Use Time:{}", System.currentTimeMillis() - start);
}
Service与Impl:
File download(Vo vo);
@Override
public File downloadProperty(Vo vo) {
File tempFile = null;
try {
long start = System.currentTimeMillis();
tempFile = File.createTempFile("vehical", ".csv");
CsvWriter csvWriter = new CsvWriter(tempFile.getCanonicalPath(), ',', Charset.forName("UTF-8"));
csvWriter.writeRecord(ExportInfoConstant.PROPERTY_HEAD_INFO);
log.info("导入header文件耗时:{}ms", System.currentTimeMillis() - start);
Mapper.download(vo, new ResultHandler<Entity>() {
@Override
public void handleResult(ResultContext<? extends Entity> resultContext) {
Entity o = resultContext.getResultObject();
try {
csvWriter.write(o.getGameItem());
csvWriter.write(o.getPropertyName());
csvWriter.write(o.getPropertyType());
csvWriter.write(DateUtils.getStrFromDate(o.getCreateTime()));
csvWriter.write(DateUtils.getStrFromDate(o.getUpdateTime()));
} catch (Exception e) {
log.error("导出异常,异常信息:{}",e.getMessage());
}
}
});
} catch (IOException e) {
log.error("download GameProperty error:{}", e.getMessage());
}
return tempFile;
}
Mapper(mybatis流式查询):
@Select("<script>" +
...
"</script>")
@Options(resultSetType = ResultSetType.FORWARD_ONLY, fetchSize = 1000)
@ResultType(Entity.class)
void download(@Param("Vo")Vo vo, ResultHandler<Entity> handler);
CsvUtil(自己写的封装方法):
@Slf4j
public class CsvUtil {
public static void outCsvStream(HttpServletResponse response, File tempFile, String fileName) {
OutputStream out = null;
FileInputStream in = null;
if (tempFile == null) {
log.error("file not exit");
return;
}
try {
out = response.getOutputStream();
byte[] b = new byte[10240];
File fileLoad = new File(tempFile.getCanonicalPath());
String dateTimeInfo = DateUtils.format(new Date());
response.reset();
response.setContentType("application/csv");
response.setHeader("content-disposition", "attachment; filename="+ URLEncoder.encode(fileName,"UTF-8")+"_"+dateTimeInfo +".csv");
in = new FileInputStream(fileLoad);
int n;
out.write(new byte[] {( byte ) 0xEF, ( byte ) 0xBB, ( byte ) 0xBF });
while ((n = in.read(b)) != -1) {
out.write(b, 0, n);
}
} catch (IOException e) {
log.error("导出{}文件异常,异常信息:{}", fileName, e.getMessage());
} finally {
if (null != in) {
try {
in.close();
} catch (IOException e) {
log.error("输入流关闭异常,异常信息:{}", e.getMessage());
}
if (null != out) {
try {
out.close();
} catch (IOException e) {
log.error("response输出流关闭异常,异常信息:{}", e.getMessage());
}
}
}
}
}
public static boolean deleteFile(File file) {
if (file.exists() && file.isFile()) {
if (file.delete()) {
log.info("文件删除成功");
return true;
} else {
return false;
}
} else {
return false;
}
}
public static void writeHeader(CsvWriter csvWriter, Object o) throws IOException {
Field[] fields = o.getClass().getDeclaredFields();
String[] headers = new String[fields.length];
for (int i = 0; i < fields.length; i++) {
fields[i].setAccessible(true);
headers[i] = fields[i].getName();
}
csvWriter.writeRecord(headers);
}
public static void writeBody(CsvWriter csvWriter, Object o) {
try {
Field[] fields = o.getClass().getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
fields[i].setAccessible(true);
String getter = "get" + StringUtils.capitalize(fields[i].getName());
Method method = o.getClass().getMethod(getter, new Class[]{});
Object value = method.invoke(o, new Object[]{});
if (null == value) {
csvWriter.write(" ");
} else {csvWriter.write(value.toString());
}
}
csvWriter.endRecord();
} catch (Exception e) {
log.info("获取属性值失败!" + e, e);
}
}
}
|