讀取數據庫內容並生成excel,從服務器上導出excel時已下載文件的方式在瀏覽器展示

 1、pom文件導入的依賴:

        <!-- POI -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>3.17</version>
        </dependency>

 2、封裝的導出excel的工具類TemplateExcelUtil:(如果想用導入的封裝方法,可以聯繫我:573969466)

package com.zy.zs.utils;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.*;

import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.*;

public class TemplateExcelUtil<T> {

    /**
     * 導出excel
     * 這是一個通用的方法,利用了JAVA的反射機制,可以將放置在JAVA集合中並且符號一定條件的數據以EXCEL 的形式輸出
     * temp         模板路徑
     * target       存儲目標地址
     * params       表頭裏的參數數組
     * headersId    表格屬性列名對應的javaBean字段---你需要導出的字段名(爲了更靈活控制你想要導出的字段)
     *  dtoList     需要顯示的數據集合,集合中一定要放置符合javabean風格的類的對象
     * 返回響應體
     */
    public  void exportExcel(InputStream temp,String target, String[] params,List<String> headersId,
                            List<T> dtoList) {
    	
        /*(二)字段*/
        Map<Integer, String> titleFieldMap = new HashMap<>();
        int value = 0;
        for (int i = 0; i < headersId.size(); i++) {
            if (!headersId.get(i).equals(null)) {
                titleFieldMap.put(value, headersId.get(i));
                value++;
            }
        }
        
        /* (三)讀取模板*/
        //XSSFWorkbook wb = null;
        Workbook wb = null;
       // File file = new File(temp);
        try {  
              //wb = (XSSFWorkbook) WorkbookFactory.create(new FileInputStream(file));
            //wb=WorkbookFactory.create(new FileInputStream(file));
            wb=WorkbookFactory.create(temp);
            } catch (FileNotFoundException e) {  
              e.printStackTrace();  
            } catch (InvalidFormatException e) {  
              e.printStackTrace();  
            } catch (IOException e) {  
              e.printStackTrace();  
            }  

        /** 得到第一個sheet */
        Sheet sheet=wb.getSheetAt(0);
       // XSSFSheet sheet = wb.getSheetAt(0);
        sheet.setDefaultColumnWidth((short)20);
        //補充標題頭的參數
        /*XSSFRow row0 = sheet.getRow(1);
        XSSFCell cell00 = row0.getCell(0);
        String string00 = MessageFormat.format(cell00.getStringCellValue(),params);
        cell00.setCellValue(string00);*/

        
        //得到表格的樣式
        //XSSFCellStyle cellStyle = sheet.getRow(1).getCell(0).getCellStyle();
        CellStyle cellStyle = sheet.getRow(1).getCell(0).getCellStyle();

        //XSSFRow row=null;
        //XSSFCell cell=null;
        Row row=null;
        Cell cell=null;
        //表格標題一行的字段的集合
        Collection zdC = titleFieldMap.values();
        Iterator<T> labIt = dtoList.iterator();//總記錄的迭代器
        //int zdRow =1;//列序號
        int zdRow =0;
        while (labIt.hasNext()) {//記錄的迭代器,遍歷總記錄
            int zdCell = 0;
            zdRow++;
            row = sheet.createRow(zdRow);
            T l = (T) labIt.next();
            // 利用反射,根據javabean屬性的先後順序,動態調用getXxx()方法得到屬性值
            Field[] fields = l.getClass().getDeclaredFields();//獲得JavaBean全部屬性
            for (short i = 0; i < fields.length; i++) {//遍歷屬性,比對
                Field field = fields[i];
                String fieldName = field.getName();//屬性名
                Iterator<String> zdIt = zdC.iterator();//一條字段的集合的迭代器
                while (zdIt.hasNext()) {//遍歷要導出的字段集合
                    if (zdIt.next().equals(fieldName)) {//比對JavaBean的屬性名,一致就寫入,不一致就丟棄
                        String getMethodName = "get"
                                + fieldName.substring(0, 1).toUpperCase()
                                + fieldName.substring(1);//拿到屬性的get方法
                        Class tCls = l.getClass();//拿到JavaBean對象
                        try {
                            Method getMethod = tCls.getMethod(getMethodName,
                                    new Class[] {});//通過JavaBean對象拿到該屬性的get方法,從而進行操控
                            Object val = getMethod.invoke(l, new Object[] {});//操控該對象屬性的get方法,從而拿到屬性值
                            Class t = getMethod.getReturnType();
                            cell = row.createCell((short) zdCell);
                            cell.setCellStyle(cellStyle);//單元格樣式
                            //根據值的類型設置單元格的值
                            switch (t.getName()) {
							case "java.lang.Integer":
							    if(null!=val){
							    	cell.setCellValue((Integer)val);
							    }
							    break;
							case "java.util.Date":
								if(null!=val){
									Date date=(Date)val;
									SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
								    cell.setCellValue(sdf.format(date));
								}
							    break;
							default:
								cell.setCellValue(String.valueOf(val));
								break;
							}
                            zdCell++;
                        } catch (SecurityException e) {
                            e.printStackTrace();
                        } catch (IllegalArgumentException e) {
                            e.printStackTrace();
                        } catch (NoSuchMethodException e) {
                            e.printStackTrace();
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        } catch (InvocationTargetException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
      //4.存儲文件
        try {
			FileOutputStream out=new FileOutputStream(target);
		    wb.write(out);
		    out.flush();
		    out.close();
        } catch (FileNotFoundException e) {

           e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
}

3、 前臺jsp頁面:不能用ajax與後臺進行交互

//導出發貨單
    function sendOrder() {
        if(confirm("您確定要導出發貨單嗎?")){
            location.href="${pageContext.request.contextPath}/poi/poiFile?merchantId=6";
        }
    }

4、 controller方法:

把數據庫數據導出,先生成excel表格到服務器,然後再從服務器下載到本地。然後再刪除服務器上的excel表格

package com.zy.zs.controller.orderController;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zy.pojo.*;
import com.zy.zs.bean.FTPBean;
import com.zy.zs.common.ResultUtil;
import com.zy.zs.feign.PoiService;
import com.zy.zs.utils.FtpUtil;
import com.zy.zs.utils.TemplateExcelUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/poi")
@PropertySource(value = {"classpath:all.properties"})
public class PoiController {
    @Resource
    private PoiService service;
    @Value("${Excel_Export_Address}")
    private String address;
    @Autowired
    private FTPBean ftpBean;
    //ftp服務器的文件夾名
    @Value("${Excel_Address}")
    private String Excel_Address;

    private List<OrderExpressOrder> orderExpressOrders = null;


    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
/**
     * poi:把數據庫數據導出,先生成excel表格到服務器,然後再從服務器下載到本地。然後再刪除服務器上的excel表格
     * 導出發貨單
     *
     * @RequestMapping("/poiFile") 我是根據session裏的用戶名和訂單狀態進行的sql語句查詢
     */
    @RequestMapping("/poiFile")
    public String poiFile(HttpSession session,
                          OrderParam orderParam,
                          HttpServletRequest request,
                          HttpServletResponse response) throws IOException {
        String json = JSONObject.toJSONString(orderParam);
        //這是要導出到excel表格裏的地址,我的命名方式用了時間戳的形式(sendOrder_5698740745687.xlsx)
        String target = address + File.separator + "sendOrder" + "_" + System.currentTimeMillis() + ".xls";
        if (!new File(address).exists()) {
            new File(address).mkdirs();
        }
        //模板名稱
        String temp = "sendOrder.xls";
        String templatePath="/temp/";
        ServletContext context = request.getSession().getServletContext();
        InputStream is= context.getResourceAsStream(templatePath + "/" + temp);
       
        //參數列表,模板裏有幾個參數需要定義,就寫幾個參數
        String[] params = new String[0];
        //導出發貨單
        List<OrderDispatchBill> list = service.findDispatchBill(json);
        //Excel表對應的JavaBean屬性的集合
        List<String> list1 = propertyList();
        //new一個工具類對象
        TemplateExcelUtil excelUtil = new TemplateExcelUtil();
        //調用工具類中的導出方法,並傳入參數
        excelUtil.exportExcel(is, target, params, list1, list);

        File fileurl = new File(target);
        //瀏覽器下載後的文件名稱showValue,從url中截取到源文件名稱以及,以及文件類型,如board.docx;
        String showValue = target;
        try {
            //根據條件得到文件路徑
            System.out.println("===========文件路徑===========" + fileurl);
            //將文件讀入文件流
            InputStream inStream = new FileInputStream(fileurl);
            //獲得瀏覽器代理信息
            final String userAgent = request.getHeader("USER-AGENT");
            //判斷瀏覽器代理並分別設置響應給瀏覽器的編碼格式
            String finalFileName = target;
            if (StringUtils.contains(userAgent, "MSIE") || StringUtils.contains(userAgent, "Trident")) {//IE瀏覽器
                finalFileName = URLEncoder.encode(showValue, "UTF8");
                System.out.println("IE瀏覽器");
            } else if (StringUtils.contains(userAgent, "Mozilla")) {//google,火狐瀏覽器
                finalFileName = new String(showValue.getBytes(), "ISO8859-1");
            } else {
                finalFileName = URLEncoder.encode(showValue, "UTF8");//其他瀏覽器
            }
            //設置HTTP響應頭
            response.reset();//重置 響應頭
            response.setContentType("application/x-download");//告知瀏覽器下載文件,而不是直接打開,瀏覽器默認爲打開
            response.addHeader("Content-Disposition", "attachment;filename=\"" + finalFileName + "\"");//下載文件的名稱

            // 循環取出流中的數據
            byte[] b = new byte[1024];
            int len;
            while ((len = inStream.read(b)) > 0) {
                response.getOutputStream().write(b, 0, len);
            }
            inStream.close();
            response.getOutputStream().close();
            //把服務器上的文件刪掉
            File f = new File(target);
            f.delete();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }
}

5、導出的excel表格如下:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章