SpringMVC在内存中直接生成Excel让用户在浏览器中直接下载使用
程序员文章站
2022-04-09 21:25:21
...
1. 如何查询出数据库的SCHEMA, 这里贴出核心的SQL语句
SELECT COLUMN_NAME AS field, COLUMN_COMMENT AS comment
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = ?
例如: name=>名称: 用户昵称, 这里我就可以用":"来分割, 只取出"名称"来. 所以, 一件方便的事情是需要很多的约定的, 尤其是团队合作中.
为了拿到一张表的字段名, 和注释, 就提取了一个公用的类:
/**
* Created with antnest-platform
* User: Vernon.Chen
* Date: 2015/3/16
* Time: 17:03
*/
@Service
public class QuerySchema {
@Resource
private JdbcTemplate jdbcTemplate;
public List<Map<String, Object>> getSchemaByTableName(String tableName) {
if (StringUtils.isBlank(tableName)) {
return null;
}
List<Map<String, Object>> schema = new ArrayList<Map<String, Object>>();
StringBuilder sqlSB = new StringBuilder();
sqlSB.append(" SELECT COLUMN_NAME AS field, COLUMN_COMMENT AS comment ");
sqlSB.append(" FROM INFORMATION_SCHEMA.COLUMNS ");
sqlSB.append(" WHERE table_name = ? ");
schema = jdbcTemplate.queryForList(sqlSB.toString(), new Object[]{tableName});
if (schema != null && schema.size() > 0) {
for (Map<String, Object> map : schema) {
String comment = (String) map.get("comment");
if (StringUtils.isNotBlank(comment) && comment.indexOf(":") > -1) {
map.put("comment", comment.substring(0, comment.indexOf(":")));
}
}
}
return schema;
}
}
下面就是如何生成Excel呢? 也是比较总要的一步. 生成Excel我所知道jar包有2个, 一个是jxl.jar, 还有一个就是项目中用到的poi.
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${poi.version}</version>
</dependency>
<poi.version>3.10-FINAL</poi.version>
然后开看一个组装Excel的代码. 由于不需要将生成的文件持久化到本地, 所以直接返回byte[]就好.
@Override
public byte[] selectExcel() throws Exception {
ByteArrayOutputStream out = null;
try {
HSSFWorkbook workbook = new HSSFWorkbook();
generateExcelForAs(cellMapper.selectExcel(), workbook);
out = new ByteArrayOutputStream();
HSSFWorkbook hssWb = (HSSFWorkbook) workbook;
hssWb.write(out);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return out.toByteArray();
}
private void generateExcelForAs(List<Map<String, Object>> list, HSSFWorkbook workbook) {
if (list == null || list.size() == 0) {
return ;
}
List<Map<String, Object>> title = querySchema.getSchemaByTableName("t_cell");
int excelRow = 0;
try {
HSSFSheet sheet = workbook.createSheet();
for (int i = 0; i < list.size(); i++) {
if (i == 0) {
Map<String, Object> first = list.get(0);
// 添加标题
int column = 0;
HSSFRow row = sheet.createRow(excelRow);
for (Map<String, Object> map : title) {
row.createCell(column).setCellValue(map.get("comment").toString());
column++;
}
excelRow++;
column = 0;
// 还需添加第1行的数据, 从0开始
row = sheet.createRow(excelRow);
for (Map<String, Object> map : title) {
if (!first.containsKey(map.get("field"))) {
column++;
} else {
String value = first.get(map.get("field")) == null ? "" : first.get(map.get("field")).toString();
row.createCell(column).setCellValue(value);
column++;
}
}
excelRow++;
} else {
HSSFRow row = sheet.createRow(excelRow);
Map<String, Object> rowMap = list.get(i);
int column = 0;
for (Map<String, Object> map : title) {
if (!rowMap.containsKey(map.get("field"))) {
column++;
} else {
String value = rowMap.get(map.get("field")) == null ? "" : rowMap.get(map.get("field")).toString();
row.createCell(column).setCellValue(value);
column++;
}
}
excelRow++;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
这里就返回了想要的byte[].
最后一步就是在Response里返回流了.
@RequestMapping(value = "/xxx")
public void cell(HttpServletResponse response) throws Exception {
byte[] bytes = cellService.selectExcel();
response.setContentType("application/x-msdownload");
response.setHeader("Content-Disposition", "attachment;filename=" + UUIDUtil.getUUID() + ".xls");
response.setContentLength(bytes.length);
response.getOutputStream().write(bytes);
response.getOutputStream().flush();
response.getOutputStream().close();
}
response.setContentType("application/x-msdownload");
response.setHeader("Content-Disposition", "attachment;filename=" + UUIDUtil.getUUID() + ".xls");
一个是告诉浏览器需要下载, 下面一个就是告诉流程器下载是的文件名字. 这里我用的UUID.
至此, 就完全OK了
转载于:https://my.oschina.net/vernon/blog/389039