NPOI导出表格
数据展示一般用网格,有时要导出到客户端本地处理,本文试用NPOI控件实现;
1、前端方法一,XMLHttpRequest
因为$.ajax参数dataType选项不支持blob,使用了XMLHttpRequest对象;
<script type="text/javascript"> //判断是否IE function _isIE() { if (!!window.ActiveXObject || "ActiveXObject" in window) return true; else return false; } //导出Excel响应操作 $("#btnconfirm").click(function () { //导出选中字段 var $selected = $("#selecteditem>select option"); var data = []; //构造json数组 for (var i = 0; i < $selected.length; i++) { data.push({ "value": $selected.eq(i).attr("value"), "text": $selected.eq(i).text() }); } //转换为字符串 var paramStr = JSON.stringify(data); //获取查询字符串 var ClassId = window.location.search; //请求地址 var url = '../Handlers/ExportExcel.ashx' + ClassId; //实例化对象xhr var xhr = new XMLHttpRequest(); //打开链接 xhr.open('post', url, true); //设置响应类型为blob,只能用小写 xhr.responseType = 'blob'; //导出Excel文件 xhr.onload = function () { if (xhr.readyState == 4 && xhr.status == 200) { //获取响应头信息、文件名 var ContentDisposition =decodeURI(xhr.getResponseHeader("Content-Disposition")); var filename = ContentDisposition.substring(ContentDisposition.lastIndexOf('filename=')+9); //接收响应数据 var content = this.response; //流数据转为Blob var blob = new Blob([content]); saveAs(blob, filename); } }; //设置http请求头 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); //带参发送请求 xhr.send("param=" + paramStr); }); //输出文件链接 function saveAs(blob, filename) { //生成一个a标签 var a = document.createElement('a'); a.style.display = 'none'; a.download = filename; a.id = "aexport"; //生成一个label标签,用于触发a标签点击事件 var lb = document.createElement('label'); lb.for = "aexport"; a.appendChild(lb); //创建一个URL对象,指向Blob对象 var objectURL = window.URL.createObjectURL(blob); a.href = objectURL; //把a标签加入body document.body.appendChild(a); //触发a标签点击事件 lb.click(); //IE不支持createObjectURL,特殊处理 if (_isIE()) { window.navigator.msSaveOrOpenBlob(blob, filename); } //删除a标签 document.body.removeChild(a); //回收内存 URL.revokeObjectURL(objectURL); } </script>
2、前端方法二,表单模拟
文件名为响应头信息中filename;如果返回字符串,可以使用iframe接收,即 form.target = iframe.name ,iframe接收完成后, iframe.onload=function(){} 获取返回字符串处理;
<script type="text/javascript"> //导出Excel响应操作 $("#btnconfirm").click(function () { //导出选中字段 var $selected = $("#selecteditem>select option"); var data = []; //构造json数组,value为字段名,text为字段描述 for (var i = 0; i < $selected.length; i++) { data.push({ "value": $selected.eq(i).attr("value"), "text": $selected.eq(i).text() }); } //转换为字符串,作为post上传参数 var paramStr = JSON.stringify(data); //获取查询字符串 var ClassId = window.location.search; //请求地址 var url = '../Handlers/ExportExcel.ashx' + ClassId; //生成一个input标签,用于读取数据 var input = document.createElement('input'); input.type = 'text'; input.name = 'param'; input.value = paramStr; //生成一个form标签,用于发送数据 var form = document.createElement('form'); form.method = 'post'; form.action = url; form.hidden = 'hidden'; //把input加入表单 form.appendChild(input); //把表单加入body document.body.appendChild(form); //表单提交 form.submit();
document.body.removeChild(form); }); </script>
3、前端方法三,直接跳转
如果固定导出格式,没有需要上传的参数,或者用Get方式传递参数,直接跳转也可以,文件名为响应头信息中filename;
<input type="button" value="导出学生到Excel" id="btnExportExcelStu" hidden/>
//测试导出 var btnExportExcelStu = document.getElementById('btnExportExcelStu'); btnExportExcelStu.onclick = function() { window.location.href = "@Url.Content("~ / Handlers / ExportExcel.ashx ? ClassId = 2 ")"; }
4、后端采用一般处理程序
public class ExportExcel : IHttpHandler { public void ProcessRequest(HttpContext context) { //获取传入参数 string param = context.Request["param"]; //反序列化字符串,存入字典列表,内容为待导出字段,value为字段名,text为字段描述 List<Dictionary<string, string>> listDic = null; if (!(param.Length==0)) { JavaScriptSerializer jss = new JavaScriptSerializer(); listDic = jss.Deserialize<List<Dictionary<string, string>>>(param); } //设置输出类型 context.Response.ContentType = "blob"; //将HTTP头添加到输出流,设置导出文件名 string filename = HttpUtility.UrlEncode(DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-ffff")+".xls"); context.Response.AddHeader("Content-Disposition", "attachment;filename=" + filename); //创建Excel工作簿和工作表 HSSFWorkbook workbook = new HSSFWorkbook(); ISheet worksheet = workbook.CreateSheet("Sheet1"); //添加批注 HSSFPatriarch patr = (HSSFPatriarch)worksheet.CreateDrawingPatriarch(); List<HSSFComment> listcomm = new List<HSSFComment>(); //动态生成列批注 string value = ""; for (int i = 0; i < listDic.Count(); i++) { /*参考网站如下,2019-11-20 * https://www.cnblogs.com/zhuangjolon/p/9300704.html * 关于HSSFClientAnchor(dx1,dy1,dx2,dy2,col1,row1,col2,row2)的参数,有必要在这里说明一下: * dx1:起始单元格的x偏移量; * dy1:起始单元格的y偏移量; * dx2:终止单元格的x偏移量; * dy2:终止单元格的y偏移量; * col1:起始单元格列序号; * row1:起始单元格行序号; * col2:终止单元格列序号; * row2:终止单元格行序号; * 其实主要是前四个是偏移量,后四个关系到批注的位置和大小。 */ listcomm.Add(patr.CreateComment(new HSSFClientAnchor(7, 12, 0, 0, i + 1, 1, i + 3, 5))); //获取导出字段名,设置为列批注 listDic[i].TryGetValue("value", out value); listcomm[i].String = new HSSFRichTextString(value); } //创建工作表表头 IRow rowHeader = worksheet.CreateRow(1); //动态生成列标题 for (int i = 0; i < listDic.Count(); i++) { //获取导出字段描述,设置列标题和批注 listDic[i].TryGetValue("text", out value); ICell rowHeadercell = rowHeader.CreateCell(i, CellType.String); rowHeadercell.SetCellValue(value); rowHeadercell.CellComment = listcomm[i]; } //获取参数 string ClassId = context.Request.QueryString["ClassId"]; //查询数据 List<StudentExt> stulist = new ScoreListService().GetScoreByClass(ClassId); //创建数据行 for (int i = 0; i < stulist.Count; i++) { IRow rowContent = worksheet.CreateRow(i + 2); for (int k = 0; k < listDic.Count(); k++) { //获取导出字段名 listDic[k].TryGetValue("value", out value); //返回实例类型 Type t = stulist[i].GetType(); //获取value属性并取值 var proValue = t.GetProperty(value).GetValue(stulist[i], null); string proType = proValue.GetType().Name; //单元格赋值 string cellValue = string.Empty; //日期只要年月日 if (proType != "DateTime") { cellValue = proValue.ToString(); }else { cellValue = Convert.ToDateTime(proValue).ToString("yyyy-MM-dd"); } rowContent.CreateCell(k, CellType.String).SetCellValue(cellValue); } } //将Excel工作簿写入输出流 workbook.Write(context.Response.OutputStream); } }
5、后端采用MVC
//将Excel工作簿写入输出流 MemoryStream ms = new MemoryStream(); workbook.Write(ms); string fileDownloadName = HttpUtility.UrlEncode(filename + '.' + filetype); var fcr = File(ms.ToArray(), "appliction/x-excel", fileDownloadName); return fcr;
参考资料:
- https://blog.csdn.net/zhou13528482267/article/details/89474648
- https://segmentfault.com/a/1190000017946900
- https://www.cnblogs.com/xuanbingbingo/p/8621755.html
- https://blog.csdn.net/u010736165/article/details/80744628
- https://blog.csdn.net/qq_34169240/article/details/84231226
- https://www.cnblogs.com/HappyYawen/p/8623852.html