AJAX文件下载
===================================================================
2016年netty/mina/java nio视频教程java游戏服务器设计教程
互联网架构师教程: http://blog.csdn.net/pplcheer/article/details/71887910
互联网架构师视频课程 Dubbo ActiveMQ spring Netty MongoDB Jvm :http://blog.csdn.net/pplcheer/article/details/72794970
需要的加qq:1225462853,备注:程序员学习视频
其他视频都可以索要(Netty NET C++ 等等)
===================================================================
JQuery的ajax函数的返回类型只有xml、text、json、html等类型,没有“流”类型,所以我们要实现ajax下载,不能够使用相应的ajax函数进行文件下载。但可以用js生成一个form,用这个form提交参数,并返回“流”类型的数据。在实现过程中,页面也没有进行刷新。
注意此示例采用STRUTS2实现,没有采用Struts2内置的文件下载方法。
JS代码如下:
- <script type="text/javascript">
- function aClick () {
- $.ajax({
- type : "POST", //提交方式
- url : "${pageContext.request.contextPath}/ajaxTest.action",//路径
- data : {
- id: 1,
- name:"testtt"
- },//数据,这里使用的是Json格式进行传输
- success : function(result) {//返回数据根据结果进行相应的处理
- var form=$("<form>");//定义一个form表单
- form.attr("style","display:none");
- form.attr("target","");
- form.attr("method","post");
- form.attr("action","downloadTest.action");
- var input1=$("<input>");
- input1.attr("type","hidden");
- input1.attr("name","exportData");
- input1.attr("value",(new Date()).getMilliseconds());
- $("body").append(form);//将表单放置在web中
- form.append(input1);
- form.submit();//表单提交
- }
- });
- }
- </script>
下图有两个超链接,第一个是通过AJAX调用下载ACTION的,第二个直接就是超链接调用ACTION 。
- <%@ page language="java" contentType="text/html; charset=UTF-8"
- pageEncoding="UTF-8"%>
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <script src='full/jquery.min.js'></script>
- <title>Insert title here</title>
- <script type="text/javascript">
- function aClick () {
- $.ajax({
- type : "POST", //提交方式
- url : "${pageContext.request.contextPath}/ajaxTest.action",//路径
- data : {
- id: 1,
- name:"testtt"
- },//数据,这里使用的是Json格式进行传输
- success : function(result) {//返回数据根据结果进行相应的处理
- var form=$("<form>");//定义一个form表单
- form.attr("style","display:none");
- form.attr("target","");
- form.attr("method","post");
- form.attr("action","ajaxTest.action");
- var input1=$("<input>");
- input1.attr("type","hidden");
- input1.attr("name","exportData");
- input1.attr("value",(new Date()).getMilliseconds());
- $("body").append(form);//将表单放置在web中
- form.append(input1);
- form.submit();//表单提交
- }
- });
- }
- </script>
- </head>
- <body>
- <br />
- <h2>点击下载</h2>
- <a href="javascript:void(0)" onclick="aClick()">文件下载</a>
- <a href="ajaxTest.action?fileName=FCN301-Ver.1.1費用申請書.xls">文件下载(超链接)</a>
- </body>
- </html>
补充一个按钮的点击事件方法
- $( '#eventButton' ).click(function(){
- var dFrame=$("<iframe>");
- dFrame.attr("style","display: none");
- dFrame.attr("name","downloadFrame");
- dFrame.attr("src","excelDownloadServlet?filePath=C:/TEMP/FCN301-Ver.1.1費用申請書.xls");
- $("body").append(dFrame);
- });
ACTION类如下:(此ACTION类中也有一个下载的方法,都是共通的)
- /**
- * com.ppl.action.excelDol.java
- * @author 作者 : pplsunny
- * @version 创建时间:2017年4月8日 下午8:26:39
- * 类说明
- */
- package com.ppl.action;
- import java.io.BufferedInputStream;
- import java.io.BufferedOutputStream;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import org.apache.struts2.ServletActionContext;
- import com.opensymphony.xwork2.ActionSupport;
- import com.ppl.test.WorkbookDemo;
- /**
- * XXXX
- */
- public class excelDol extends ActionSupport {
- public String execute() throws Exception {
- String filePath="G:/POI_JAVA/FCN301-Ver.1.1費用申請書.xls";
- //下载到客户端
- HttpServletResponse response = ServletActionContext.getResponse();
- //download(filePath,response);
- WorkbookDemo.readTempleteExcel(filePath, response);
- //1 获取表单数据
- HttpServletRequest request = ServletActionContext.getRequest();
- String id = request.getParameter("id");
- String name = request.getParameter("name");
- System.out.println(id+"--"+name);
- return NONE;
- }
- private void download(String path, HttpServletResponse response) {
- try {
- // path是指欲下载的文件的路径。
- File file = new File(path);
- // 取得文件名。
- String filename = file.getName();
- String strName = new String(filename.getBytes("UTF-8"), "ISO-8859-1");
- // 以流的形式下载文件。
- InputStream fis = new BufferedInputStream(new FileInputStream(path));
- byte[] buffer = new byte[fis.available()];
- fis.read(buffer);
- fis.close();
- // 清空response
- response.reset();
- // 设置response的Header
- response.addHeader("Content-Disposition", "attachment;filename="
- + new String(filename.getBytes("UTF-8"), "ISO-8859-1"));
- response.addHeader("Content-Length", "" + file.length());
- OutputStream toClient = new BufferedOutputStream(
- response.getOutputStream());
- response.setContentType("application/vnd.ms-excel;charset=gb2312");
- toClient.write(buffer);
- toClient.flush();
- toClient.close();
- } catch (IOException ex) {
- ex.printStackTrace();
- }
- }
- }
EXCEL文件操作类
- package com.ppl.test;
- import java.io.BufferedInputStream;
- import java.io.BufferedOutputStream;
- import java.io.ByteArrayInputStream;
- import java.io.ByteArrayOutputStream;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.net.URLEncoder;
- import java.text.DecimalFormat;
- import java.text.SimpleDateFormat;
- import java.util.Calendar;
- import java.util.Date;
- import java.util.Iterator;
- import javax.servlet.http.HttpServletResponse;
- import org.apache.poi.hssf.usermodel.HSSFCell;
- import org.apache.poi.hssf.usermodel.HSSFDateUtil;
- 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.poifs.filesystem.POIFSFileSystem;
- import org.apache.poi.ss.usermodel.Cell;
- import org.apache.poi.ss.usermodel.CellStyle;
- import org.apache.poi.ss.usermodel.CreationHelper;
- import org.apache.poi.ss.usermodel.Row;
- import org.apache.poi.ss.usermodel.Sheet;
- import org.apache.poi.ss.usermodel.Workbook;
- import org.apache.poi.ss.usermodel.WorkbookFactory;
- import org.apache.poi.ss.util.WorkbookUtil;
- public class WorkbookDemo {
- /**
- * 创建工作簿
- * @throws IOException
- */
- public static void createWorkBook() throws IOException {
- /**
- * 工作薄: WorkBook是操作Excel的入口,Excel的文档对象,HSSFWorkbook(2003版本 ), XSSFWorkbook(2007版本)实现了该接口。
- * HSSF对应xls格式,XSSF对应xlsx格式
- * ------------------------------------------------------------------
- * Workbook wb = new XSSFWorkbook();
- * FileOutputStream fileOut = new FileOutputStream("workbook.xlsx");
- * wb.write(fileOut);
- * fileOut.close();
- * ------------------------------------------------------------------
- */
- final Workbook HSSFwb = new HSSFWorkbook();
- /**
- * Sheet是在org.apache.poi.ss.usermodel包的接口,它是创建具有特定名称的高或低级别的电子表格的所有类的超接口。
- * 页:Sheet表示工作薄的分页。HSSFSheet, XSSFChartSheet, XSSFDialogsheet, XSSFSheet实现了该接口。
- * 索引以0开始,以workbook.getNumberOfSheets()-1结束
- */
- final String safeName = WorkbookUtil.createSafeSheetName("first sheet");
- final Sheet sheet = HSSFwb.createSheet(safeName);
- //sheet.autoSizeColumn(6, true);
- /**
- * 获取工作簿数量
- */
- final int sheetCount = HSSFwb.getNumberOfSheets();
- System.out.println("sheetCount: " + sheetCount);
- /**
- * Row:表示页中的一行。HSSFRow, XSSFRow实现了该接口。
- * Row的索引以0开始(getFirstRowNum),以getLastRowNum结束
- */
- final Row row = sheet.createRow((short) 0);
- /**
- * 得到的是最后一个不为空的行索引,真实行号是【getLastRowNum()+1】
- */
- final int rowNumReal = sheet.getLastRowNum();
- /**
- * Cell:行中的一个单元格。HSSFCell, XSSFCell实现了该接口。
- * Cell的索引以0开始(getFirstCellNum),以getLastCellNum结束,
- */
- final Cell cell = row.createCell(0);
- /**
- * 获取当前行中不为空的单元格数
- */
- final int cellNumReal = row.getPhysicalNumberOfCells();
- /**
- * 空单元格返回对应的单元格类型
- */
- Cell cell2 = row.getCell(3, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
- cell2 = row.getCell(4, Row.MissingCellPolicy.RETURN_BLANK_AS_NULL);
- cell2 = row.getCell(5, Row.MissingCellPolicy.RETURN_NULL_AND_BLANK);
- //设置单元格的数据
- cell.setCellValue(1);
- // Or do it on one line.
- row.createCell(1).setCellValue(1.2);
- row.createCell(2).setCellValue("This is a string 速度反馈链接");
- row.createCell(3).setCellValue(true);
- //----------------------单元格赋值示例START------------------------------------------
- /**
- * 创建第十行
- */
- final Row rowTEN = sheet.createRow((short) 9);
- // 填充日期类型的数据---未设置Cell Style
- rowTEN.createCell(1).setCellValue(new Date());
- // 另一种创建日期的方法
- rowTEN.createCell(2).setCellValue(Calendar.getInstance());
- /**
- * 在第十行的单元格上创建单元格
- */
- final Cell cellOther = rowTEN.createCell(5);
- cellOther.setCellValue(new Date());
- /**
- * 获取HSSF的辅助类
- */
- final CreationHelper createHelper = HSSFwb.getCreationHelper();
- final CellStyle cellStyle = HSSFwb.createCellStyle();
- // 填充日期类型的数据---已设置Cell Style
- final String timeFormat = "yyyy-MM-dd hh:mm:ss";
- cellStyle.setDataFormat(createHelper.createDataFormat().getFormat(timeFormat));
- final Cell cell7 = rowTEN.createCell(6);
- cell7.setCellValue(new Date());
- cell7.setCellStyle(cellStyle);
- /**
- * 设置单元格宽度自适应,对中文支持不好
- */
- sheet.autoSizeColumn((short) 6);
- //----------------------单元格赋值示例END------------------------------------------
- /**
- * 创建一个文件 命名为workbook.xls,默认创建到当前工程的根目录下
- */
- final FileOutputStream fileOut = new FileOutputStream("workbook2.xls");
- /**
- * 把上面创建的工作簿输出到文件中
- */
- HSSFwb.write(fileOut);
- /**
- * 关闭输出流
- */
- fileOut.close();
- HSSFwb.close();
- }
- /**
- * 使用POI读入excel工作簿文件
- * @throws Exception
- */
- public static void readWorkBook() throws Exception {
- /**
- * 从文件流读取Excel
- */
- final InputStream inp = new FileInputStream("workbook1.xls");
- /**
- * 根据上述创建的输入流 创建工作簿对象
- */
- final Workbook wb = WorkbookFactory.create(inp);
- /**
- * 页Sheet是从0开始索引的
- */
- final Sheet sheet = wb.getSheetAt(0);
- /**
- * 按名引用excel工作表
- * Sheet sheetByName = wb.getSheet("NAME");
- */
- /**
- * 获取工作簿的行数
- */
- final int rowNumReal = sheet.getLastRowNum();
- System.out.println("----------------------");
- System.out.println("rowNumReal-->" + rowNumReal);
- System.out.println("----------------------");
- final int cellNumReal = sheet.getRow(rowNumReal).getPhysicalNumberOfCells();
- System.out.println("cellNumReal-->" + cellNumReal);
- //利用foreach循环 遍历sheet中的所有行
- int rowNum=0;
- /**
- * 直接采用这种循环空行和空列是不会读取的,
- * 即当行有空行或者一行中有空单元格是,循环会跳过去
- */
- for (final Row row : sheet) {
- rowNum++;
- //遍历row中的所有方格
- for (final Cell cell : row) {
- final String valueT = getCellContentAsString(cell);
- System.out.println(cell.toString() + " ---> " + valueT);
- }
- //每一个行输出之后换行
- System.out.println();
- }
- System.out.println("----------------------");
- loopRowAndCell(sheet);
- System.out.println("rowNum-->"+rowNum);
- //关闭输入流
- inp.close();
- }
- /**
- * 遍历一个工作簿中的行和列
- * 不包含空行和空列(无需对空行和空列做处理)
- * @param sheet
- * @throws Exception
- */
- public static void loopRealRowAndCell(final Sheet sheet) throws Exception {
- /**
- * 遍历行
- */
- int rowno = 0;
- for (final Iterator itemRow = sheet.rowIterator(); itemRow.hasNext();) {
- final Row row = (Row) itemRow.next();
- rowno++;
- System.out.println("----------rowno----------" + rowno);
- /**
- * 遍历列
- */
- for (final Iterator itemCell = row.cellIterator(); itemCell.hasNext();) {
- final Cell cell = (Cell) itemCell.next();
- /**
- * 获取单元格格式类型
- * POI 3.15 beta 3. Use CellType.ERROR instead.
- */
- String cellValue = "";
- switch (cell.getCellTypeEnum()) {
- case STRING:// 字符串
- cellValue = cell.getRichStringCellValue().getString().trim();
- break;
- case NUMERIC:// 数字
- //如果为时间格式的内容
- if (HSSFDateUtil.isCellDateFormatted(cell)) {
- final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- cellValue = sdf.format(HSSFDateUtil.getJavaDate(cell.getNumericCellValue())).toString();
- break;
- } else {
- /**
- * 解决科学计数法的问题
- */
- final Double d = cell.getNumericCellValue();
- final DecimalFormat dformat = new DecimalFormat("#.##");
- cellValue = dformat.format(d);
- }
- break;
- case BOOLEAN:// Boolean
- cellValue = String.valueOf(cell.getBooleanCellValue()).trim();
- break;
- case FORMULA:// 公式
- /**
- * 解决公式的取值问题
- */
- try {
- /**
- * 公式计算结果是纯数字
- */
- cellValue = String.valueOf(cell.getNumericCellValue());
- } catch (final IllegalStateException e) {
- /**
- * 公式计算结果是不是纯数字
- */
- cellValue = String.valueOf(cell.getRichStringCellValue());
- }
- /**
- * 这句获取的是计算公式
- */
- //cellValue = cell.getCellFormula() + "";
- break;
- case BLANK: // 空值
- cellValue = "BLANG";
- break;
- case ERROR: // 故障
- cellValue = "N/A";
- break;
- default://未知类型
- cellValue = "ERROR";
- }
- System.out.println(" cellValue---> " + cellValue);
- }
- }
- }
- /**
- * 遍历一个工作簿中的行和列
- * 包含空行和空列(传统遍历,需要对空行和空列进行处理)
- * @param sheet
- * @throws Exception
- */
- public static void loopRowAndCell(final Sheet sheet) throws Exception {
- /**
- * 得到的是最后一个不为空的行索引,真实行号是【getLastRowNum()+1】
- */
- final int rowNumReal = sheet.getLastRowNum();
- /**
- * 遍历行
- */
- for (int rowIndex = 0; rowIndex <= rowNumReal; rowIndex++) {
- /**
- * 获取当前行
- */
- final Row row = sheet.getRow(rowIndex);
- /**
- * 空行处理
- */
- if (null == row) {
- System.out.println(" BLANG ROW " + rowIndex);
- continue;
- }
- /**
- * 取得当前行的列数
- */
- final int cellCount = row.getLastCellNum();
- /**
- * 遍历列
- */
- for (int cellIndex = 0; cellIndex < cellCount; cellIndex++) {
- /**
- * 获取当前列,如果当前列不存在(为空)则返回一个单元格类型为空的单元格
- */
- final Cell cell = row.getCell(cellIndex, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
- /**
- * 空列处理
- */
- if (null == cell) {
- System.out.println(" BLANG CELL " + cellIndex);
- continue;
- }
- /**
- * 获取单元格格式类型
- * POI 3.15 beta 3. Use CellType.ERROR instead.
- */
- String cellValue = "";
- switch (cell.getCellTypeEnum()) {
- case STRING:// 字符串
- cellValue = cell.getRichStringCellValue().getString().trim();
- break;
- case NUMERIC:// 数字
- //如果为时间格式的内容
- if (HSSFDateUtil.isCellDateFormatted(cell)) {
- final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- cellValue = sdf.format(HSSFDateUtil.getJavaDate(cell.getNumericCellValue())).toString();
- break;
- } else {
- /**
- * 解决科学计数法的问题
- */
- final Double d = cell.getNumericCellValue();
- final DecimalFormat dformat = new DecimalFormat("#.##");
- cellValue = dformat.format(d);
- }
- break;
- case BOOLEAN:// Boolean
- cellValue = String.valueOf(cell.getBooleanCellValue()).trim();
- break;
- case FORMULA:// 公式
- /**
- * 解决公式的取值问题
- */
- try {
- /**
- * 公式计算结果是纯数字
- */
- cellValue = String.valueOf(cell.getNumericCellValue());
- } catch (final IllegalStateException e) {
- /**
- * 公式计算结果是不是纯数字
- */
- cellValue = String.valueOf(cell.getRichStringCellValue());
- }
- /**
- * 这句获取的是计算公式
- */
- //cellValue = cell.getCellFormula() + "";
- break;
- case BLANK: // 空值
- cellValue = "BLANG";
- break;
- case ERROR: // 故障
- cellValue = "N/A";
- break;
- default://未知类型
- cellValue = "ERROR";
- }
- System.out.println(" cellValue---> " + cellValue);
- }
- }
- }
- /**
- *
- *解析一个单元格得到数据
- * @param cell
- * @return
- */
- private static String getCellContentAsString(final Cell cell) {
- if (null == cell) {
- return "";
- }
- /**
- * 获取单元格格式类型
- * POI 3.15 beta 3. Use CellType.ERROR instead.
- */
- String cellValue = "";
- switch (cell.getCellTypeEnum()) {
- case STRING:// 字符串
- cellValue = cell.getRichStringCellValue().getString().trim();
- break;
- case NUMERIC:// 数字
- //如果为时间格式的内容
- if (HSSFDateUtil.isCellDateFormatted(cell)) {
- final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- cellValue = sdf.format(HSSFDateUtil.getJavaDate(cell.getNumericCellValue())).toString();
- break;
- } else {
- /**
- * 解决科学计数法的问题
- */
- final Double d = cell.getNumericCellValue();
- final DecimalFormat dformat = new DecimalFormat("#.##");
- cellValue = dformat.format(d);
- }
- break;
- case BOOLEAN:// Boolean
- cellValue = String.valueOf(cell.getBooleanCellValue()).trim();
- break;
- case FORMULA:// 公式
- /**
- * 解决公式的取值问题
- */
- try {
- /**
- * 公式计算结果是纯数字
- */
- cellValue = String.valueOf(cell.getNumericCellValue());
- } catch (final IllegalStateException e) {
- /**
- * 公式计算结果是不是纯数字
- */
- cellValue = String.valueOf(cell.getRichStringCellValue());
- }
- /**
- * 这句获取的是计算公式
- */
- //cellValue = cell.getCellFormula() + "";
- break;
- case BLANK: // 空值
- cellValue = "BLANG";
- break;
- case ERROR: // 故障
- cellValue = "N/A";
- break;
- default://未知类型
- cellValue = "";
- }
- return cellValue;
- }
- /**
- *
- * 读取已有Excel作为模板进行数据操作
- * @param filePAth 模板路径
- * @return -1:filePAth error;
- * @throws IOException
- * @throws FileNotFoundException
- */
- public static int readTempleteExcel(final String filePAth,HttpServletResponse response) throws FileNotFoundException, IOException {
- if ((filePAth == null) || filePAth.trim().isEmpty()) {
- return -1;
- }
- /**
- * 先读取模板 ,使用POIFSFileSystem对象构造的新HSSFWorkbook对象。
- */
- final POIFSFileSystem POIfs = new POIFSFileSystem(new FileInputStream(filePAth));
- /**
- * 基于模板创建workbook
- */
- final HSSFWorkbook workbook = new HSSFWorkbook(POIfs);
- /**
- * 如果模板存在多页的话可以分别取到
- */
- final HSSFSheet sheet_1st = workbook.getSheetAt(0);
- //------------------------
- // 第一页,第一行
- final HSSFRow row = sheet_1st.getRow(0);
- // 取第一个单元格
- final HSSFCell cell = row.getCell(0);
- // 获取单元格字符串值
- final String cellValue = cell.getStringCellValue();
- System.out.println(cellValue);
- //final String path = "G:/POI_JAVA/demo.xls";
- // 输出Excel
- HttpServletResponse newresponse=response;
- try {
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- workbook.write(os);// HSSFWorkbook写入流
- byte[] content = os.toByteArray();
- InputStream is = new ByteArrayInputStream(content);
- //文件名字符编码转换
- //String strName = new String(filename.getBytes("UTF-8"), "ISO-8859-1");
- // 设置请求
- // 设置response参数,可以打开下载页面
- newresponse.reset();
- newresponse.setContentType("application/octet-stream");
- newresponse.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("aa.xls", "UTF-8"));
- OutputStream outputStream = newresponse.getOutputStream();// 打开流
- BufferedInputStream bis = null;
- BufferedOutputStream bos = null;
- bis = new BufferedInputStream(is);
- bos = new BufferedOutputStream(outputStream);
- byte[] buff = new byte[2048];
- int bytesRead;
- // Simple read/write loop.
- while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
- bos.write(buff, 0, bytesRead);
- }
- if (bis != null){
- bis.close();
- }
- if (bos != null){
- bos.close();
- }
- outputStream.flush();// 刷新流
- outputStream.close();// 关闭流
- workbook.close();
- } catch (final IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return 0;
- }
- }
==================