xlsm文件就是带宏的Excel文件
POI和EasyExcel都是无法创建xlsm文件的。xlsm文件只能在Excel里面另存为xlsm文件。我通过自己的尝试,发现POI和EasyExcel创建xlsm虽然不会报错,但是打开文件都是提示损坏,而wps又能正常打开。
POI和EasyExcel创建xlsm本质上应该都是把文件的后缀改为.xlsm,因为我把生成的损坏的xlsm文件后缀改为xlsx,可以正常打开。
POI创建xlsm文件不会报错,但是打开下载的文件时候会报错文件已损坏
这是因为POI只能对已有的xlsm文件进行查询与更改,而不能创建xlsm文件
当需求需要能下载xlsm文件时,解决办法就是在服务器中放一个正常的xlsm文件,然后用POI对文件进行清空,放上需要的数据传给接口再下载到本地。
以下是部分源码
@Permission("")
@RequestMapping("/exportData")
public void exportData(@RequestParam(value = "table") String table,
@RequestParam(value = "uploadTime", required = false) String uploadTime,
@RequestParam("tid") Integer tid
, @RequestParam(value = "ym", required = false) String ym) {
File file1 = new File(uploadPath + table + ".xlsm");
table = table.trim().toUpperCase();
User user = (User) session.getAttribute("login");
List<Mapping> mapping = insertConfigService.findMappingList(table, db);
//List<com.gr.entity.master.Mapping> mapping = dataMappingService.findMappingByTable(table);
//模板表中文名
String excelname = mapping.get(0).getTableNote();
if (file1.exists()) {//存在
//将数据放入服务器上的excel
Path filePath = Paths.get(file1.toString());
// declare a workbook
XSSFWorkbook workbook;
try {
/*
* READING from the .xlsx file:
*/
FileInputStream in = new FileInputStream(filePath.toFile());
workbook = XSSFWorkbookFactory.createWorkbook(in);
XSSFSheet sheet = workbook.getSheetAt(0);
FileOutputStream out1 = new FileOutputStream(filePath.toAbsolutePath().toString());
sheet = workbook.getSheetAt(0);
// create new cells and write the words into them
//清空标题和数据
for (int i = 1; i <= sheet.getLastRowNum(); i++) {
XSSFRow row3 = sheet.getRow(i);
for (int j = 0; j < row3.getLastCellNum(); j++) {
XSSFCell cell = row3.getCell(j);
cell.setCellValue("");
}
}
//添加标题
XSSFRow row1 = sheet.createRow(0);
for (int j = 0; j < cols.size(); j++) {
XSSFCell cell = row1.createCell(j);
cell.setCellValue(cols.get(j));
}
//添加数据
for (int i = 1; i <= data.size(); i++) {
XSSFRow row = sheet.createRow(i);
for (int j = 0; j < data.get(0).size(); j++) {
XSSFCell cell = row.createCell(j);
cell.setCellValue(data.get(i - 1).get(j).toString());
}
}
// close the FileInputStream
in.close();
// write the workbook using the FileOutputStream
workbook.write(out1);
// force the FileOutputStream to write everything until it is empty
out1.flush();
// close the FileOutputStream
out1.close();
// close the workbook.
workbook.close();
} catch (FileNotFoundException e) {
System.err.println(
"The file \"" + filePath.toAbsolutePath().toString() + "\" could not be found.");
e.printStackTrace();
} catch (IOException e) {
System.err.println("Error while reading the file \"" + filePath.toAbsolutePath().toString() + "\"");
e.printStackTrace();
} catch (EmptyFileException e) {
System.err.println("The supplied file \"" + filePath.toAbsolutePath().toString() + "\" is empty.");
e.printStackTrace();
}
//从服务器上下载
response.setCharacterEncoding("UTF-8");
response.setHeader("content-Type", "application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(excelname, "UTF-8") + ".xlsm");
response.setHeader("Pragma", URLEncoder.encode(excelname, "UTF-8"));
byte[] buffer = new byte[1024];
FileInputStream fis = null; //文件输入流
BufferedInputStream bis = null;
OutputStream os = null; //输出流
os = response.getOutputStream();
fis = new FileInputStream(file1);
bis = new BufferedInputStream(fis);
int len = 0;
while ((len = bis.read(buffer)) > 0) {
os.write(buffer, 0, len);
}
bis.close();
fis.close();
return;
}
//写文件
EasyExcel.write(response.getOutputStream()).head(heads).registerWriteHandler(new HeadWriteHandlerImpl(mapping.size(), mm)).registerWriteHandler(new Custemhandler()).sheet("Sheet1").doWrite(data);
//将文件下载到固定地址
EasyExcel.write(file1.toString()).head(heads).registerWriteHandler(new HeadWriteHandlerImpl(mapping.size(), mm)).registerWriteHandler(new Custemhandler()).sheet("Sheet1").doWrite(data);
//xlsx转xlsm
}