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;
}