1. 程式人生 > >web匯出excel--------java匯出檔案彈出下載框讓使用者選擇路徑

web匯出excel--------java匯出檔案彈出下載框讓使用者選擇路徑

實現匯出檔案時 彈出下載框 主要是 設定成 檔案流  stream 型別的response. 瀏覽器就會識別出 檔案下載彈出 下載框。

這裡總結三個方式

web-sturts框架中彈出

詳見 

其中關鍵的設定是

<struts>        
   <package name="struts2" extends="struts-default">        
       <action name="FileDownload" class="com.struts2.filedownload.FileDownload">  
           <result name="success" type="stream">  
               <param name="contentType">text/plain</param>  
               <param name="contentDisposition">attachment;fileName="${fileName}"</param>  
               <param name="inputName">downloadFile</param>  
               <param name="bufferSize">1024</param>  
           </result>  
       </action>  
     
   </package>  
     
</struts>  


web-SpringMvc等非struts框架中彈出

在response中設定頭

response.addHeader("Content-Disposition", "attachment;filename="+ new String(filename.getBytes()));  
           OutputStream os= new BufferedOutputStream(response.getOutputStream());  
           response.setContentType("application/vnd.ms-excel;charset=gb2312");  
           os.write(buffer);  
           os.flush();  
           os.close();  

例如:

jsp頁面 使用js    提交 post  form

    $(document).ready(function() {    
    	var $searchForm = $('#search_form').on('submit',function(){
        	$dt.DataTable().searchEx( {} ).draw();
        	return false;
        }).on('click', 'button.export', function(){ 
        var searchData={};
        searchData.search=$('#search_form').formGet();  
          console.log(searchData);
           post('/order/list/export',searchData);        	
        });
              
              
      function post(URL, PARAMS) {        
        var temp = document.createElement("form");        
        temp.action = URL;        
        temp.method = "post";        
        temp.style.display = "none";        
        for (var x in PARAMS.search) {        
           var opt = document.createElement("textarea"); 
           if(x=="id"||x=="expressNumber"||x=="payStatus"){      
             opt.name = x;        
             opt.value = PARAMS.search[x];
             temp.appendChild(opt);  
           }       
        }        
        document.body.appendChild(temp);        
        temp.submit(); 
      }  
}

後端接受引數後查詢出資料,把生成的excel寫入excel,返回檔案流
	@RequestMapping("/list/export")
	public Object export(@RequestParam String id,@RequestParam  String expressNumber,@RequestParam String payStatus,HttpServletResponse response) {
		PagerRequest<Map> req=new PagerRequest<Map>();
		req.setLength(0);
		req.setOffset(0);
		HashMap<String, String> search=new HashMap<String, String>();
		search.put("id", id);
		search.put("expressNumber", expressNumber);
		search.put("payStatus", payStatus);
		req.setSearch(search);
		List<Order> orders = new ArrayList<Order>();
		if (req.getSearch() == null||req.getSearch().size()==0) {
			orders = (List<Order>) orderRepository.findAll();
		} else {
			Page<Order> page = orderRepository.listWithSearch(new PageRequest(
					0,(int) orderRepository.count()), req
					.getSearch());
			orders = page.getContent();
		}
		if (productService.exportOrders(orders,response)) {
			return null;
		}
		return null; 

	}


	@Override
		public boolean exportOrders(List<Order> orders, HttpServletResponse response) {
			try {

				ArrayList<String[]> contentsArrayList = new ArrayList<String[]>();
				String[] titles = new String[14];
				titles[0] = "訂單日期";
				titles[1] = "訂單支付日期";
				titles[2] = "訂單編號";
				titles[3] = "產品名稱";
				titles[4] = "產品型別";
				titles[5] = "單價";
				titles[6] = "購買數量";
				titles[7] = "總金額";
				titles[8] = "付款狀態";
				titles[9] = "收件人名稱";
				titles[10] = "收件人電話";
				titles[11] = "配送地址";
				titles[12] = "配送日期";
				titles[13] = "發票資訊";
				contentsArrayList.add(titles);
				for (int i = 0; i < orders.size(); i++) {
					List<BuyList> butlists = orders.get(i).getBuyList();
					for (BuyList buyList : butlists) {
						String[] content = new String[14];
						content[0] = orders.get(i).getCreateDate();
						content[1] = orders.get(i).getPayDate();
						content[2] = orders.get(i).getId();
						content[3] = buyList.getProductName();
						content[4] = buyList.getProductTypeStr();
						if(buyList.getProductPrice()!=null){
							content[5]=buyList.getProductPrice().toString();	
						}						
						content[6] = String.valueOf(buyList.getProductCount());
						content[7] = orders.get(i).getTotalMoney();
						content[8] = orders.get(i).getPayStatus() == Order.PAY_PAIY ? "已付款"
								: "未付款";
						content[9] = orders.get(i).getName();
						content[10] = orders.get(i).getMobile();
						content[11] = orders.get(i).getAddress();
						OrderStatus orderStatus=orders.get(i).getOrderStatus();
						if(orderStatus!=null){
							HistoryStatus historyStatus=orderStatus.getCurrent();
							if(historyStatus!=null){
								if(historyStatus.getStatus()==OrderStatus.STATUS_SEND_OUT){
								content[12] =historyStatus.getDatetime();	
								}
							}
						}
						content[13] = orders.get(i).isHasInvoice() == true ? "是"
								: "否";
						contentsArrayList.add(content);
					}
				}
				String[][] contents = ExcelUtils.changeToArray(contentsArrayList);				
				String fileName = ExcelUtils.writeExcel(contents, "訂單",response);
			    return true;
			} catch (Exception e) {
				e.printStackTrace();

			}
			return false;
		}

public static String writeExcel(String[][] titles, String title, HttpServletResponse response) throws IOException {
		String fileName =title
				+ Calendar.getInstance().getTimeInMillis();
		response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename="+ new String((fileName + ".xls").getBytes(), "iso-8859-1"));
        //根據傳進來的file物件建立可寫入的Excel工作薄  
        OutputStream os = response.getOutputStream();  
			WritableWorkbook wwb = null;
			try {
				// 首先要使用Workbook類的工廠方法建立一個可寫入的工作薄(Workbook)物件

				wwb = Workbook.createWorkbook(os);
			} catch (IOException e) {
				e.printStackTrace();
			}
			if (wwb != null) {
				// 建立一個可寫入的工作表
				// Workbook的createSheet方法有兩個引數,第一個是工作表的名稱,第二個是工作表在工作薄中的位置
				WritableSheet ws = wwb.createSheet(title, 1);

				// 下面開始新增單元格
				for (int row = 0; row < titles.length; row++) {
					// System.out.println(row);
					for (int j = 0; j < titles[row].length; j++) {
						// 這裡需要注意的是,在Excel中,第一個引數表示列,第二個表示行
						Label labelC = new Label(j, row, titles[row][j]);

						try {
							// 將生成的單元格新增到工作表中
							ws.addCell(labelC);
						} catch (RowsExceededException e) {
							e.printStackTrace();
						} catch (WriteException e) {
							e.printStackTrace();
						}
					}
				}

				try {
					// 從記憶體中寫入檔案中
					wwb.write();			 
					// 關閉資源,釋放記憶體
					wwb.close();
					os.flush();
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				} catch (WriteException e) {
					e.printStackTrace();
				}
			}
			return fileName;
		}
	

	
	public static String[][] changeToArray(ArrayList<String[]> contentsArrayList) {
		String[][] contents = new String[contentsArrayList.size()][];
		for (int i = 0; i < contentsArrayList.size(); i++) {
			contents[i] = contentsArrayList.get(i);
		}
		return contents;
	}


關鍵步驟在於

1.傳入response

2.設定response的頭部檔案型別和 把工作簿寫入 response的 outputStream中即可。無需特意返回response。

response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.setHeader("Content-Disposition", "attachment;filename="+ new String((fileName + ".xls").getBytes(), "iso-8859-1"));
        //根據傳進來的file物件建立可寫入的Excel工作薄  
        OutputStream os = response.getOutputStream();  
WritableWorkbook wwb = null;
try {
           首先要使用Workbook類的工廠方法建立一個可寫入的工作薄(Workbook)物件
wwb = Workbook.createWorkbook(os);

ps: jsp中請求的action 記得要return null,因為 已經包含了 檔案流的response。

如果不是return null的話則會衝突報錯。

優化

jsp頁面 使用js    提交 post  form

    $(document).ready(function() {    
    	var $searchForm = $('#search_form').on('submit',function(){
        	$dt.DataTable().searchEx( {} ).draw();
        	return false;
        }).on('click', 'button.export', function(){ 
        var searchData={};
        searchData.search=$('#search_form').formGet();  
          console.log(searchData);
           post('/order/list/export',searchData);        	
        });
              
              
      function post(URL, PARAMS) {        
        var temp = document.createElement("form");        
        temp.action = URL;        
        temp.method = "post";        
        temp.style.display = "none";        
        for (var x in PARAMS.search) {        
           var opt = document.createElement("textarea"); 
           if(x=="id"||x=="expressNumber"||x=="payStatus"){      
             opt.name = x;        
             opt.value = PARAMS.search[x];
             temp.appendChild(opt);  
           }       
        }        
        document.body.appendChild(temp);        
        temp.submit(); 
      }  
}

controller.class接收

@RequestMapping("/product-upgrade/list/export")
    public void export(HttpServletRequest request, HttpServletResponse response) {
        Map<String, String> search = new HashMap<>();
        Enumeration<String> parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            String key = parameterNames.nextElement();
            search.put(key, request.getParameter(key));
        }
        Query query = new Query();
        Criteria criteria = new Criteria();
        criteria.and("upgradeList").exists(true);
        if (!StringUtils.isBlank(search.get("mobile")))
            criteria.and("mobile").is(search.get("mobile"));
        if (!StringUtils.isBlank(search.get("payStatus")))
            criteria.and("payStatus").is(Integer.parseInt(search.get("payStatus")));

        if (!StringUtils.isBlank(search.get("upgradeStatus"))) {
        	if("0".equals(search.get("upgradeStatus"))) {
        		  criteria.orOperator(Criteria.where("upgradeStatus").exists(false), Criteria.where("upgradeStatus").is(0));
        	}else {
            criteria.and("upgradeStatus").is(Integer.parseInt(search.get("upgradeStatus")));
        	}
        } 
   
        if (!StringUtils.isEmpty(search.get("beginTime"))
                || !StringUtils.isEmpty(search.get("endTime"))) {
            criteria = criteria.and("createDate");
            if (!StringUtils.isEmpty(search.get("beginTime")))
                criteria.gte(DateUtils.parse(search.get("beginTime")));
            if (!StringUtils.isEmpty(search.get("endTime")))
                criteria.lte(DateUtils.parse(search.get("endTime")));

        }
        query.addCriteria(criteria);
        query.with(new Sort(Sort.Direction.DESC, "createDate"));
        List<Order> list = mongoTemplate.find(query, Order.class);
        exportProductUpgradeOrder(list, response);
    }





@Override
    public boolean exportProductUpgradeOrder(List<Order> orders, HttpServletResponse response) {
        try {
 
            ArrayList<String[]> contentsArrayList = new ArrayList<>();
            String[] titles = new String[]{
                    "訂單編號", "訂單名稱", "唾液盒編號", "手機", "總金額", "線上支付",
                    "支付狀態", "升級狀態", "建立時間", "升級備註"};

            Boolean[] titleNumFlags = new Boolean[]{
                    false, false, false, false, true, true,
                    false, false, false, false};// 是否是數值型的標識

            contentsArrayList.add(titles);
            for (Order order : orders) {
                String[] content = new String[titles.length];
                content[0] = order.getId();
                content[1] = order.getOrderName();
                content[2] = order.getUpgradeList().get(0).getBarcode();
                content[3] = order.getMobile();
                content[4] = String.valueOf(order.getTotalMoney());
                content[5] = String.valueOf(order.getPayMoney());
                content[6] = order.getPayStatus() == Order.PAY_UNPAY ? "未付款" : "已付款";
                content[7] = order.getUpgradeStatus() == 1 ? "已處理" : "未處理";
                content[8] = order.getCreateDate();
                content[9] = order.getUpgradeRemark();
                contentsArrayList.add(content);
            }
            ExcelUtils.writeExcel(ExcelUtils.changeToArray(contentsArrayList), "匯出", response, titleNumFlags);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }


ExcelUtils.class

package com.mofang.util;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Calendar;

import javax.servlet.http.HttpServletResponse;

import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;

/**
 * ExcelUtils 匯出excel
 * 
 * @author joe
 * 
 */
public class ExcelUtils {

    /**
     * 生成一個Excel檔案
     * 
     * @param title 工作表的名稱
     * @param titles 工作表的內容
     */

    public static String writeExcel(String[][] titles, String title,
            HttpServletResponse response, Boolean[] titleNumFlags)
            throws IOException {
        String fileName = title + Calendar.getInstance().getTimeInMillis();
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename="
                + new String((fileName + ".xls").getBytes(), "iso-8859-1"));
        // 根據傳進來的file物件建立可寫入的Excel工作薄
        OutputStream os = response.getOutputStream();
        WritableWorkbook wwb = null;
        try {
            // 首先要使用Workbook類的工廠方法建立一個可寫入的工作薄(Workbook)物件

            wwb = Workbook.createWorkbook(os);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (wwb != null) {
            // 建立一個可寫入的工作表
            // Workbook的createSheet方法有兩個引數,第一個是工作表的名稱,第二個是工作表在工作薄中的位置
            WritableSheet ws = wwb.createSheet(title, 1);
            jxl.write.NumberFormat nf = new jxl.write.NumberFormat("#0.00"); // 設定數字格式
            jxl.write.WritableCellFormat wcfN = new jxl.write.WritableCellFormat(
                    nf); // 設定表單格式
            // 下面開始新增單元格
            for (int row = 0; row < titles.length; row++) {
                // System.out.println(row);
                for (int j = 0; j < titles[row].length; j++) {
                    if (titleNumFlags[j]) {// 當數值型時先轉換成double
                        try {
                            double titlesDoubleValue = Double
                                    .parseDouble(titles[row][j]);
                            ws = writeNumberToWs(ws, wcfN, row, j,
                                    titlesDoubleValue);
                        } catch (Exception notnum) {
                            String titlesStringValue = titles[row][j];
                            // 這裡需要注意的是,在Excel中,j表示列,row表示行
                            ws = writeStringToWs(ws, row, j, titlesStringValue);
                        }
                    } else {
                        String titlesStringValue = titles[row][j];
                        // 這裡需要注意的是,在Excel中,j表示列,row表示行
                        ws = writeStringToWs(ws, row, j, titlesStringValue);
                    }
                }
            }

            try {
                // 從記憶體中寫入檔案中
                wwb.write();
                // 關閉資源,釋放記憶體
                wwb.close();
                os.flush();
                os.close();
            } catch (IOException | WriteException e) {
                //e.printStackTrace();
            }
        }
        return fileName;
    }

    private static WritableSheet writeNumberToWs(WritableSheet ws,
            jxl.write.WritableCellFormat wcfN, int row, int j,
            double titlesDoubleValue) {
        jxl.write.Number labelNF = new jxl.write.Number(j, row,
                titlesDoubleValue, wcfN); // 格式化數值
        try {
            ws.addCell(labelNF);
        } catch (WriteException e1) {
            e1.printStackTrace();
        }
        return ws;
    }

    private static WritableSheet writeStringToWs(WritableSheet ws, int row,
            int j, String titlesStringValue) {
        Label labelC = new Label(j, row, titlesStringValue);
        try {
            // 將生成的單元格新增到工作表中
            ws.addCell(labelC);
        } catch (WriteException e) {
            e.printStackTrace();
        }
        return ws;
    }

    public static String[][] changeToArray(ArrayList<String[]> contentsArrayList) {
        String[][] contents = new String[contentsArrayList.size()][];
        for (int i = 0; i < contentsArrayList.size(); i++) {
            contents[i] = contentsArrayList.get(i);
        }
        return contents;
    }

}



桌面程式-swing彈出

swing只會在伺服器中彈出,多用於 桌面程式-----如果用在web中則 在頁面點選時,選擇框在伺服器彈出。

swing

public static String writeExcel(String[][] titles, String title) {

		String fileName = "";
		JFileChooser dialog = new JFileChooser();
		dialog.setDialogTitle("儲存檔案");
		dialog.setFileSelectionMode(JFileChooser.FILES_ONLY);
		FileSystemView fsv = FileSystemView.getFileSystemView();
		System.out.println(fsv.getHomeDirectory()); // 得到桌面路徑
		dialog.setCurrentDirectory(fsv.getHomeDirectory()); // 設定預設儲存路徑為桌面路徑
		// dialog.setDialogType(JFileChooser.SAVE_DIALOG);
		dialog.setSelectedFile(new File("訂單列表"
				+ Calendar.getInstance().getTimeInMillis() + ".xls")); // 設定預設檔名
		dialog.setFileFilter(new TextFileFilter("*.xls", "文字文件(*.xls)"));
		int result = dialog.showSaveDialog(dialog);
		if (result == JFileChooser.APPROVE_OPTION) {
			File file = dialog.getSelectedFile();
			fileName = file.getAbsolutePath(); // 得到檔案全名

			WritableWorkbook wwb = null;
			try {
				// 首先要使用Workbook類的工廠方法建立一個可寫入的工作薄(Workbook)物件

				wwb = Workbook.createWorkbook(new File(fileName));
			} catch (IOException e) {
				e.printStackTrace();
			}
			if (wwb != null) {
				// 建立一個可寫入的工作表
				// Workbook的createSheet方法有兩個引數,第一個是工作表的名稱,第二個是工作表在工作薄中的位置
				WritableSheet ws = wwb.createSheet(title, 1);

				// 下面開始新增單元格
				for (int row = 0; row < titles.length; row++) {
					// System.out.println(row);
					for (int j = 0; j < titles[row].length; j++) {
						// 這裡需要注意的是,在Excel中,第一個引數表示列,第二個表示行
						Label labelC = new Label(j, row, titles[row][j]);

						try {
							// 將生成的單元格新增到工作表中
							ws.addCell(labelC);
						} catch (RowsExceededException e) {
							e.printStackTrace();
						} catch (WriteException e) {
							e.printStackTrace();
						}
					}
				}

				try {
					// 從記憶體中寫入檔案中
					wwb.write();
					// 關閉資源,釋放記憶體
					wwb.close();
				} catch (IOException e) {
					e.printStackTrace();
				} catch (WriteException e) {
					e.printStackTrace();
				}
			}
		}
		return fileName;
	}