工作中经常会有将后台数据以Excel导出的功能。
简单的方法有将response的contentType设置为application/vnd.ms-excel;
或在JSP页面直接设置成:
<%@page contentType="application/vnd.ms-excel; charset=GBK"%>
但,如何将数据写入到一个事先写好VBA和各种公式的Excel模版中,再响应给界面下载呢。
大致思路是,新建一个临时xls文件,获得xlt模版文件的输入流写入数据,再将这个输入流通过临时xls文件的输出流,将带有数据的模版生成这个临时xls文件,即最终要下载的Excel文件。
直接上代码。
1 File file = null;
2 HSSFSheet st = null;
3 HSSFWorkbook wb = null;
4 POIFSFileSystem fs = null;
5 FileOutputStream fos = null;
6
7 //建立临时文件,也是要下载的Excel文件。临时文件的路径为JDK针对不同操作系统定义的临时目录。
8 file = File.createTempFile("test", ".xls");
9 fs = new POIFSFileSystem(new FileInputStream(new File("Format.xlt")));//参数为Excel模版的输入流,可用其它方式。
10 wb = new HSSFWorkbook(fs);
11 st = wb.getSheetAt(0);
12 for(int row = 1; row < 100; row++){
13 for(int col = 0; col < 10; col++){
14 ExcelUtils.setValue(st, row, col, "test"+row+col);//循环写入数据
15 }
16 }
17 fos = new FileOutputStream(file);
18 try{
19 if (wb != null) {
20 wb.write(fos);
21 }
22 if (fos != null) {
23 fos.close();
24 }
25 } catch (NullPointerException ex){
26 }
27 //文件下载。
28 ExcelUtils.downFile(response, file, "application/vnd.ms-excel;charset=GBK");
ExcelUtils工具类的代码如下,其中包含了Excel数据读取的部分:
1 /** 2 * Excel工具类 3 */ 4 package *.*.*.*; 5 6 import javax.servlet.http.HttpServletResponse; 7 8 import java.io.*; 9 import java.text.DecimalFormat; 10 import java.text.SimpleDateFormat; 11 import java.util.*; 12 13 import org.apache.poi.hssf.usermodel.*; 14 import org.apache.poi.poifs.filesystem.POIFSFileSystem; 15 16 public class ExcelUtils { 17 /** 18 * 从Excel文件得到二维数组,每个sheet的第一行为标题 19 * 20 * @param file Excel文件 21 * @return 22 * @throws FileNotFoundException 23 * @throws IOException 24 */ 25 public static String[][] getData(File file) throws FileNotFoundException, 26 IOException { 27 return getData(file, 1); 28 } 29 30 /** 31 * 从Excel文件得到二维数组 32 * 33 * @param file Excel文件 34 * @param ignoreRows 忽略的行数,通常为每个sheet的标题行数 35 * @return 36 * @throws FileNotFoundException 37 * @throws IOException 38 */ 39 public static String[][] getData(File file, int ignoreRows) 40 throws FileNotFoundException, IOException { 41 ArrayList result = new ArrayList(); 42 int rowSize = 0; 43 BufferedInputStream in = new BufferedInputStream(new FileInputStream( 44 file)); 45 // 打开HSSFWorkbook 46 POIFSFileSystem fs = new POIFSFileSystem(in); 47 HSSFWorkbook wb = new HSSFWorkbook(fs); 48 HSSFCell cell = null; 49 for (int sheetIndex = 0; sheetIndex < wb.getNumberOfSheets(); sheetIndex++) { 50 HSSFSheet st = wb.getSheetAt(sheetIndex); 51 52 // 第一行为标题,不取 53 for (int rowIndex = ignoreRows; rowIndex <= st.getLastRowNum(); rowIndex++) { 54 HSSFRow row = st.getRow(rowIndex); 55 if (row == null) { 56 continue; 57 } 58 int tempRowSize = row.getLastCellNum() + 1; 59 if (tempRowSize > rowSize) { 60 rowSize = tempRowSize; 61 } 62 String[] values = new String[rowSize]; 63 Arrays.fill(values, ""); 64 boolean hasValue = false; 65 for (short columnIndex = 0; columnIndex <= row.getLastCellNum(); columnIndex++) { 66 String value = ""; 67 cell = row.getCell(columnIndex); 68 if (cell != null) { 69 // 注意:一定要设成这个,否则可能会出现乱码 70 cell.setEncoding(HSSFCell.ENCODING_UTF_16); 71 switch (cell.getCellType()) { 72 case HSSFCell.CELL_TYPE_STRING: 73 value = cell.getStringCellValue(); 74 break; 75 case HSSFCell.CELL_TYPE_NUMERIC: 76 if (HSSFDateUtil.isCellDateFormatted(cell)) { 77 Date date = cell.getDateCellValue(); 78 if (date != null) { 79 value = new SimpleDateFormat("yyyy-MM-dd") 80 .format(date); 81 } else { 82 value = ""; 83 } 84 } else { 85 value = new DecimalFormat("0.####").format(cell 86 .getNumericCellValue()); 87 } 88 break; 89 case HSSFCell.CELL_TYPE_FORMULA: 90 // 导入时如果为公式生成的数据则无值 91 if (!cell.getStringCellValue().equals("")) { 92 value = cell.getStringCellValue(); 93 } else { 94 value = cell.getNumericCellValue() + ""; 95 } 96 break; 97 case HSSFCell.CELL_TYPE_BLANK: 98 break; 99 case HSSFCell.CELL_TYPE_ERROR: 100 value = ""; 101 break; 102 case HSSFCell.CELL_TYPE_BOOLEAN: 103 value = (cell.getBooleanCellValue() == true ? "Y" 104 : "N"); 105 break; 106 default: 107 value = ""; 108 } 109 } 110 if (columnIndex == 0 && value.trim().equals("")) { 111 break; 112 } 113 values[columnIndex] = StringUtils.rightTrim(value); 114 hasValue = true; 115 } 116 117 if (hasValue) { 118 result.add(values); 119 } 120 } 121 } 122 in.close(); 123 String[][] returnArray = new String[result.size()][rowSize]; 124 for (int i = 0; i < returnArray.length; i++) { 125 returnArray[i] = (String[]) result.get(i); 126 } 127 return returnArray; 128 } 163 164 /** 165 * 根据contentType下载文件。 166 * @param response 响应 167 * @param File 要下载的文件源 168 * @param contentType 169 * @throws Exception 170 */ 171 public static void downFile(HttpServletResponse response, File file, String contentType) throws Exception { 172 java.io.BufferedInputStream bis = null; 173 java.io.BufferedOutputStream bos = null; 174 String destFileName = file.getPath(); 175 String shortFileName = FileUtils.getShortFileName(destFileName); 176 try{ 177 shortFileName = java.net.URLEncoder.encode(shortFileName,"UTF-8"); 178 response.setContentType(contentType); 179 response.setHeader("Content-disposition", "attachment;filename=" + shortFileName); 180 java.io.File filein = new java.io.File(destFileName); 181 java.io.FileInputStream fileInputStream = new java.io.FileInputStream(filein); 182 bis = new java.io.BufferedInputStream(fileInputStream); 183 bos = new java.io.BufferedOutputStream(response.getOutputStream()); 184 byte[] buff = new byte[2048]; 185 int bytesRead; 186 while(-1 != (bytesRead = bis.read(buff, 0, buff.length))) { 187 bos.write(buff,0,bytesRead); 188 } 189 }catch(Exception e ){ 190 e.printStackTrace(); 191 throw e; 192 }finally{ 193 if (bis != null) bis.close(); 194 if (bos != null) bos.close(); 195 } 196 } 197 198 /** 199 * 设置Cell的值 200 * 201 * @param st 202 * @param rowIndex 行坐标 203 * @param columnIndex 列坐标 204 * @param value 值 205 */ 206 public static void setValue(HSSFSheet st, int rowIndex, int columnIndex, 207 String value) { 208 if (value == null) { 209 value = ""; 210 } 211 HSSFRow row = st.getRow(rowIndex); 212 if (row == null) { 213 row = st.createRow(rowIndex); 214 } 215 HSSFCell cell = row.getCell((short) columnIndex); 216 if (cell == null) { 217 cell = row.createCell((short) columnIndex); 218 } 219 //注意:一定要设成这个,否则可能会出现乱码 220 cell.setEncoding(HSSFCell.ENCODING_UTF_16); 221 cell.setCellValue(value); 222 } 223 }
Excel工具jar包:https://files.cnblogs.com/hanmou/poi-3.0.1-FINAL-20070705.jar.zip