使用示例:

@RequestMapping(value = "/export", method = RequestMethod.GET)
public ResponseEntity<byte[]> downloadPMetricRecords(
@PathVariable(value = "resource_type") ResourceTypeEnum resourceType,
@RequestParam(value = "pool_id", required = false) String poolId,
@RequestParam(value = "business_id", required = false) String businessId,
@RequestParam(value = "organization_id", required = false) String organizationId,
@RequestParam(value = "start_time", required = false) /*@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")*/ Date starTime,
@RequestParam(value = "end_time", required = false) /*@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") */Date endTime,
@RequestParam(value = "export_format", required = false) DocFormat exportFormat,
@RequestParam(value = "statistic_type", required = false) StatisticType statisticType) throws FileNotFoundException {
PMetricExportFilterParam exportFilterParam = PMetricExportFilterParam.builder()
.resourceType(resourceType)
.poolId(poolId)
.businessId(businessId)
.organizationId(organizationId)
.startTime(starTime)
.endTime(endTime)
.exportFormat(exportFormat)
.statisticType(statisticType)
.build();
logger.info("PMetricExportController(downloadPMetricRecords) - query param: {}", exportFilterParam);
initDefaultValues(exportFilterParam);
validate(exportFilterParam);
IPMetricExportService metricExportService = metricExportServiceFactory.createMetricExportService(exportFilterParam);
return metricExportService.downloadPMetricRecords(exportFilterParam);
}

其他工具类:

package com.chinamobile.epic.tako.common.download;
import com.ssslinppp.write.AbstractWriteHandleFactory;
import com.ssslinppp.write.WriteHandler;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import java.io.*;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
* Desc:
* [large files for download, OutOfMemoryException](https://stackoverflow
* .com/questions/15800565/spring-mvc-large-files-for-download-outofmemoryexception)
* <p>
*/
@Component
public class HttpDownloadUtils {
private static final Logger logger = LoggerFactory.getLogger(HttpDownloadUtils.class);
private final static String EXCEL_2007_SUFFIX = ".xlsx";
@Value("${download.tmp.file.path: /tmp/}")
private String tmpFilePath;
/**
* HTTP下载Excel
* <p>
* 使用示例:</br>
* <blockquote><pre>{@code
* Map<String, List<PMetricDimensionTBL>> recordMap = Maps.newConcurrentMap();
* recordMap.put("sheetName001", records);
* recordMap.put("sheetName002", records);
* <p>
* String excelFileName = "pmetric-report.xlsx";
* httpDownloadUtils.httpDownloadExcel(new AbstractWriteHandleFactory<PMetricDimensionTBL>() {
* }, recordMap, excelFileName);
* }
* </pre></blockquote>
*
* @param writeHandleFactory 用于写Excel,如:{@code new AbstractWriteHandleFactory<PMetricDimensionTBL>() {
* }}
* @param recordsMap {@code Map<sheetName, records>} 待写入Excel文件的记录
* @param targetFileName 目标文件名
* @param <T> 属性中应该声明{@link com.ssslinppp.annotation.ExcelCell @ExcelCell}
* @return
* @throws FileNotFoundException
*/
public <T> ResponseEntity<byte[]> httpDownloadExcel(AbstractWriteHandleFactory<T> writeHandleFactory,
Map<String, List<T>> recordsMap,
String targetFileName) throws FileNotFoundException {
// 写入临时文件
String tmpFileToUse = tmpFilePath + UUID.randomUUID() + EXCEL_2007_SUFFIX;
WriteHandler writeHandler = writeHandleFactory.createWriteHandle(tmpFileToUse);
for (Map.Entry<String, List<T>> entry : recordsMap.entrySet()) {
writeHandler.write(entry.getKey(), entry.getValue());
}
writeHandler.flush();
// 将临时文件转换为 byte[]
byte[] fileBytes = null;
try {
InputStream in = new FileInputStream(tmpFileToUse);
fileBytes = IOUtils.toByteArray(in);
} catch (IOException e) {
logger.error("HttpDownloadUtils(exportExcel) - get byte[] from " + tmpFileToUse + " error", e);
} finally {
File file = new File(tmpFileToUse);
if (file.exists()) {
logger.info("HttpDownloadUtils(exportExcel) - delete tmp file {}", tmpFileToUse);
file.delete();
}
}
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); //文件下载需要设置: application/octet-stream
headers.setContentDispositionFormData("attachment", targetFileName); // 设置下载的文件名称
return new ResponseEntity<byte[]>(fileBytes, headers, HttpStatus.CREATED);
}
}