Java從服務端下載Excel模板文件的兩種方法

本文實例為大傢分享瞭Java從服務端下載Excel模板文件的具體實現代碼,供大傢參考,具體內容如下

方法一 (2021年01月更新)

生成excel模板

@RequestMapping("/downloadExcel")
public void downloadExcel(HttpServletResponse response, HttpServletRequest request) {
        String [] excelHeader = {"姓名","手機號(必填)","渠道名","產品名","手機操作系統(IOS/安卓)","是否是XX數據"};
        List<Object> list = new ArrayList<>();
        Object[] obj1 = {"張三","173*****311‬","a1","A","IOS","是"};
        Object[] obj2 = {"李四","138*****742","a2","B","安卓","否"};
        list.add(obj1);
        list.add(obj2);
        FileExport.exportExcel(excelHeader, list, "XXX模板", response, request);
    }

FileExport工具類:

package com.abc.common.utils.file;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 文件導出工具
 * @author abc
 * @date 2019/01/08
 */
public class FileExport {
    
    private static final Logger logger = LoggerFactory.getLogger(FileExport.class);

    /** CSV文件列分隔符 */
    private static final String CSV_COLUMN_SEPARATOR = ",";

    private static final String CSV_COLUM_TABLE = "\t";

    /** CSV文件列分隔符 */
    private static final String CSV_RN = "\r\n";

    /**
     * 導出Excel文件
     * 
     * @param excelHeader
     *            導出文件中表格頭
     * @param list
     *            導出的內容
     * @param response
     *            HttpServletResponse對象,用來獲得輸出流向客戶端寫導出的文件
     * @param sheetName
     *            Excel的sheet名稱,加上時間戳作為導出文件的名稱
     */
    public static void exportExcel(String [] excelHeader, List<Object> list, String sheetName, HttpServletResponse response, HttpServletRequest request) {
        HSSFWorkbook wb = new HSSFWorkbook();
        HSSFSheet sheet = wb.createSheet(sheetName);
        HSSFRow row = sheet.createRow((int) 0);
        /******設置單元格是否顯示網格線******/
        sheet.setDisplayGridlines(false);
        
        /******設置頭單元格樣式******/
        HSSFCellStyle style = wb.createCellStyle();
        style.setAlignment(HorizontalAlignment.CENTER);
        Font fontHeader = wb.createFont();
        fontHeader.setBold(true);
        fontHeader.setFontHeight((short) 240);
        style.setFont(fontHeader);
        style.setBorderBottom(BorderStyle.THIN);
        style.setBorderLeft(BorderStyle.THIN);
        style.setBorderRight(BorderStyle.THIN);
        style.setBorderTop(BorderStyle.THIN);
        
        /******設置頭內容******/
        for (int i = 0; i < excelHeader.length; i++) {
            HSSFCell cell = row.createCell(i);
            cell.setCellValue("  " +excelHeader[i] + "  ");
            cell.setCellStyle(style);            
        }   
        
        /******設置內容單元格樣式******/
        HSSFCellStyle styleCell = wb.createCellStyle();
        Font fontCell = wb.createFont();
        fontCell.setColor(HSSFColor.BLACK.index);
        styleCell.setAlignment(HorizontalAlignment.CENTER);
        styleCell.setFont(fontCell);
        styleCell.setBorderBottom(BorderStyle.THIN);
        styleCell.setBorderLeft(BorderStyle.THIN);
        styleCell.setBorderRight(BorderStyle.THIN);
        styleCell.setBorderTop(BorderStyle.THIN);
        /******設置單元格內容******/
        for (int i = 0; i < list.size(); i++) {
            row = sheet.createRow(i + 1);
            /******設置行高******/
            row.setHeightInPoints(20);
            Object[] obj = (Object[]) list.get(i);            
            for (int j = 0; j < excelHeader.length; j++) {
                styleCell.setWrapText(false);
                HSSFCell cell = row.createCell(j);
                if (obj[j] != null){
                     cell.setCellValue(obj[j].toString());
                }else{
                    cell.setCellValue(""); 
                }            
                //if(obj[j].toString().length()>20)
                //    styleCell.setWrapText(true);
                cell.setCellStyle(styleCell);
                sheet.autoSizeColumn(j);
            }   
        } 
        
        OutputStream ouputStream = null;
        try {
            
            String encoding = "UTF-8";
            /** 獲取瀏覽器相關的信息 */
            String userAgent = request.getHeader("user-agent");
            /** 判斷是否為msie瀏覽器 */
            if (userAgent.toLowerCase().indexOf("msie") != -1){
                 encoding = "gbk";
            }

            response.setCharacterEncoding(encoding);
            response.setContentType("application/vnd.ms-excel"); 
            String fileName = sheetName;
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHMMSS");
            fileName += (dateFormat.format(new Date())).toString()+".xls";
            response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, encoding));
            ouputStream = response.getOutputStream();   
            wb.write(ouputStream);     
            ouputStream.flush();  
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if(ouputStream!=null) {
                    ouputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 導出CSV文件
     * @param dataList 集合數據
     * @param colNames 表頭部數據
     * @param mapKey 查找的對應數據
     */
    public static boolean doExport(List<Map<String, Object>> dataList, String colNames, String mapKey, OutputStream os) {
        try {
            StringBuffer buf = new StringBuffer();

            String[] colNamesArr = null;
            String[] mapKeyArr = null;

            colNamesArr = colNames.split(",");
            mapKeyArr = mapKey.split(",");

            /******完成數據csv文件的封裝******/
            /******輸出列頭******/
            for (int i = 0; i < colNamesArr.length; i++) {
                buf.append(colNamesArr[i]).append(CSV_COLUMN_SEPARATOR);
            }
            buf.append(CSV_RN);

            if (null != dataList) {
                /******輸出數據******/
                for (int i = 0; i < dataList.size(); i++) {
                    for (int j = 0; j < mapKeyArr.length; j++) {
                        buf.append(dataList.get(i).get(mapKeyArr[j])).append(CSV_COLUM_TABLE).append(CSV_COLUMN_SEPARATOR);
                    }
                    buf.append(CSV_RN);
                }
            }
            /******寫出響應******/
            os.write(buf.toString().getBytes("GBK"));
            os.flush();
            return true;
        } catch (Exception e) {
            logger.error("doExport錯誤...", e);
        }
        return false;
    }
    
    /**
     * 設置響應格式
     * @param fileName
     * @param response
     * @throws UnsupportedEncodingException
     */
    public static void responseSetProperties(String fileName, HttpServletResponse response) throws UnsupportedEncodingException {
        /******設置文件後綴******/
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String fn = fileName + sdf.format(new Date()).toString() + ".csv";
        /******讀取字符編碼******/
        String utf = "UTF-8";

        /******設置響應******/
        response.setContentType("application/ms-txt.numberformat:@");
        response.setCharacterEncoding(utf);
        response.setHeader("Pragma", "public");
        response.setHeader("Cache-Control", "max-age=30");
        response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fn, utf));
    }
}

導出CSV文件

@GetMapping("/exportFailureRecord")
public void exportFailureRecord(String batchNumber, HttpServletResponse response) {
        if (StringUtils.isBlank(batchNumber)) {
            log.warn("失敗記錄導出失敗,批次號為空...");
            return;
        }

        //這裡根據你的業務查詢出數據
        List<ImportFailureRecord> list = importFailureRecordService.selectList(new EntityWrapper<ImportFailureRecord>()
                .eq("is_delete", 0)
                .eq("batch_number", batchNumber));
        if (CollectionUtil.isEmpty(list)) {
            log.warn("未查詢到可導出的數據...");
            return;
        }
        log.info("===========查詢到{}條可導出數據==============", list.size());

        String sTitle = "用戶姓名,手機號,失敗原因";
        String fName = "xxx失敗記錄數據_";
        String mapKey = "userName,userPhone,failureReason";

        List<Map<String, Object>> dataList = new ArrayList<>();
        for (ImportFailureRecord data : list) {
            Map<String, Object> map = new HashMap<>();
            map.put("userName", data.getUserName() == null ? "" : data.getUserName());
            map.put("userPhone", data.getUserPhone() == null ? "" : data.getUserPhone());
            map.put("failureReason", data.getFailureReason() == null ? "" : data.getFailureReason());
            dataList.add(map);
        }
        try (final OutputStream os = response.getOutputStream()) {
            log.info("=============失敗記錄導出開始============");
            FileExport.responseSetProperties(fName, response);
            FileExport.doExport(dataList, sTitle, mapKey, os);
            log.info("=============失敗記錄導出結束============");
        } catch (Exception e) {
            log.error("導出失敗記錄數據失敗", e);
        }
    }

方法二

/**
 * 描述:下載外部案件導入模板
 * @param response
 * @param request
 * @author songfayuan
 * 2018年6月7日下午5:03:59
 */
    @RequestMapping("/downloadExcel")
    @ResponseBody
    public void downloadExcel(HttpServletResponse response,HttpServletRequest request) {
        //方法一:直接下載路徑下的文件模板(這種方式貌似在SpringCloud和Springboot中,打包成JAR包時,無法讀取到指定路徑下面的文件,不知道記錯沒,你們可以自己嘗試下!!!)
        try {
            //獲取要下載的模板名稱
            String fileName = "ApplicationImportTemplate.xlsx";
            //設置要下載的文件的名稱
            response.setHeader("Content-disposition", "attachment;fileName=" + fileName);
            //通知客服文件的MIME類型
            response.setContentType("application/vnd.ms-excel;charset=UTF-8");
            //獲取文件的路徑
            String filePath = getClass().getResource("/template/" + fileName).getPath();
            FileInputStream input = new FileInputStream(filePath);
            OutputStream out = response.getOutputStream();
            byte[] b = new byte[2048];
            int len;
            while ((len = input.read(b)) != -1) {
                out.write(b, 0, len);
            }
            //修正 Excel在“xxx.xlsx”中發現不可讀取的內容。是否恢復此工作薄的內容?如果信任此工作簿的來源,請點擊"是"
            response.setHeader("Content-Length", String.valueOf(input.getChannel().size()));
            input.close();
            //return Response.ok("應用導入模板下載完成");
        } catch (Exception ex) {
            logger.error("getApplicationTemplate :", ex);
            //return Response.ok("應用導入模板下載失敗!");
        }
        
        
        //方法二:可以采用POI導出excel,但是比較麻煩(這裡類似方法一)
        /*try {
            Workbook workbook = new HSSFWorkbook();
            request.setCharacterEncoding("UTF-8");
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/x-download");
    
            
            String filedisplay = "導入模板.xls";
         
            filedisplay = URLEncoder.encode(filedisplay, "UTF-8");
            response.addHeader("Content-Disposition", "attachment;filename="+ filedisplay);
            
            // 第二步,在webbook中添加一個sheet,對應Excel文件中的sheet  
            Sheet sheet = workbook.createSheet("導入模板");
            // 第三步,在sheet中添加表頭第0行
            Row row = sheet.createRow(0);
            // 第四步,創建單元格,並設置值表頭 設置表頭居中 
            CellStyle style = workbook.createCellStyle();  
            style.setAlignment(CellStyle.ALIGN_CENTER); // 創建一個居中格式 
            
            Cell cell = row.createCell(0);  
            cell.setCellValue("商品名稱");  
            cell.setCellStyle(style); 
            sheet.setColumnWidth(0, (25 * 256));  //設置列寬,50個字符寬
            
            cell = row.createCell(1);  
            cell.setCellValue("商品編碼");  
            cell.setCellStyle(style); 
            sheet.setColumnWidth(1, (20 * 256));  //設置列寬,50個字符寬
            
            cell = row.createCell(2);  
            cell.setCellValue("商品價格");  
            cell.setCellStyle(style);  
            sheet.setColumnWidth(2, (15 * 256));  //設置列寬,50個字符寬
            
            cell = row.createCell(3);  
            cell.setCellValue("商品規格");  
            cell.setCellStyle(style);  
            sheet.setColumnWidth(3, (15 * 256));  //設置列寬,50個字符寬
            
            // 第五步,寫入實體數據 實際應用中這些數據從數據庫得到
            row = sheet.createRow(1);
            row.createCell(0, Cell.CELL_TYPE_STRING).setCellValue(1);  
            row.createCell(1, Cell.CELL_TYPE_STRING).setCellValue(2); 
            row.createCell(2, Cell.CELL_TYPE_STRING).setCellValue(3);   //商品價格
            row.createCell(3, Cell.CELL_TYPE_STRING).setCellValue(4);  //規格
        
            // 第六步,將文件存到指定位置  
            try  
            {  
                OutputStream out = response.getOutputStream();
                workbook.write(out);
                out.close();  
            }  
            catch (Exception e)  
            {  
                e.printStackTrace();  
            }  
        } catch (Exception e) {
            e.printStackTrace();
        }*/
    }

模板位置:

以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。

推薦閱讀: