public void SaveToFileTest(string path) { var fileName = Path.GetFileName(path); //var dt = _dt; var dt = PFDataHelper.DataTableGroupBy(_dt, PFDataHelper.MergeList(_pivotLeft, _pivotTop).ToArray(), new PFKeyValueCollection <SummaryType>(_pivotValue.Select(a => new PFKeyValue <SummaryType> { Key = a, Value = SummaryType.Sum })) ); //var dt = PFDataHelper.DataTableGroupBy(_dt, // _pivotTop.ToArray(), // new PFKeyValueCollection<SummaryType>(_pivotTop.Select(a => new PFKeyValue<SummaryType> { Key = a, Value = SummaryType.Sum })) // ); StoreColumnCollection columns = null; var pagingResult = PFDataHelper.PagingStore(dt, new PagingParameters { }, columns, false, null); var exporter = Exporter.Instance(pagingResult ?? new PagingResult(), new ExporterOption { FileType = "xlsx",//benjamin todo Scheme = Exporter.FinancialScheme , SheetTitle = fileName //, //SheetTitle = GetWordCMonth(cmonthff) + hr + fgsname }).FileName("总表"); //这里的下载名没用到 var export = (exporter.GetExport() as XlsxExport); //var path = Path.Combine(PFDataHelper.BaseDirectory, "output", "excelPo.xlsx"); var directoryName = Path.GetDirectoryName(path); PFDataHelper.DeleteFile(path); PFDataHelper.CreateDirectory(directoryName); export.workbook.Save(path); }
public static bool DownloadExcel(HttpContext context, Workbook workbook, string fileName, long speed) { bool ret = true; try { #region 定义局部变量 long startBytes = 0; int packSize = 1024 * 10; //分块读取,每块10K bytes var tmpFileName = Guid.NewGuid().ToString("N") + DateTime.Now.ToString("yyyyMMddHHmmss") + fileName; var path = Path.Combine(PFDataHelper.BaseDirectory, "TempFile", tmpFileName); var directoryName = Path.GetDirectoryName(path); PFDataHelper.CreateDirectory(directoryName); workbook.Save(path);//注意,当xlsx文件超过65535行时,如果调用workbook.SaveToStream方法,会使行数变少,所以暂时只想到先保存到服务器的办法 var filePath = path; FileStream myFile = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); BinaryReader br = new BinaryReader(myFile); long fileLength = myFile.Length; int sleep = (int)Math.Ceiling(1000.0 * packSize / speed);//毫秒数:读取下一数据块的时间间隔 //string lastUpdateTiemStr = File.GetLastWriteTimeUtc(filePath).ToString("r"); //string eTag = HttpUtility.UrlEncode(fileName, Encoding.UTF8) + lastUpdateTiemStr;//便于恢复下载时提取请求头; #endregion #region --验证:文件是否太大,是否是续传,且在上次被请求的日期之后是否被修改过-------------- if (myFile.Length > Int32.MaxValue) { //-------文件太大了------- context.Response.StatusCode = 413; //请求实体太大 return(false); } //if (context.Request.Headers["If-Range"] != null)//对应响应头ETag:文件名+文件最后修改时间 //{ // //----------上次被请求的日期之后被修改过-------------- // if (context.Request.Headers["If-Range"].Replace("\"", "") != eTag) // {//文件修改过 // context.Response.StatusCode = 412;//预处理失败 // return false; // } //} #endregion try { #region -------添加重要响应头、解析请求头、相关验证------------------- context.Response.Clear(); context.Response.Buffer = false; context.Response.AddHeader("Content-MD5", GetHashMD5(myFile)); //用于验证文件 context.Response.AddHeader("Accept-Ranges", "bytes"); //重要:续传必须 //context.Response.AppendHeader("ETag", "\"" + eTag + "\"");//重要:续传必须 //context.Response.AppendHeader("Last-Modified", lastUpdateTiemStr);//把最后修改日期写入响应 context.Response.ContentType = "application/octet-stream";//MIME类型:匹配任意文件类型 context.Response.AddHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(fileName, Encoding.UTF8).Replace("+", "%20")); context.Response.AddHeader("Content-Length", (fileLength - startBytes).ToString()); context.Response.AddHeader("Connection", "Keep-Alive"); context.Response.ContentEncoding = Encoding.UTF8; if (context.Request.Headers["Range"] != null) { //------如果是续传请求,则获取续传的起始位置,即已经下载到客户端的字节数------ context.Response.StatusCode = 206; //重要:续传必须,表示局部范围响应。初始下载时默认为200 string[] range = context.Request.Headers["Range"].Split(new char[] { '=', '-' }); //"bytes=1474560-" startBytes = Convert.ToInt64(range[1]); //已经下载的字节数,即本次下载的开始位置 if (startBytes < 0 || startBytes >= fileLength) { //无效的起始位置 return(false); } } if (startBytes > 0) { //------如果是续传请求,告诉客户端本次的开始字节数,总长度,以便客户端将续传数据追加到startBytes位置后---------- context.Response.AddHeader("Content-Range", string.Format(" bytes {0}-{1}/{2}", startBytes, fileLength - 1, fileLength)); } #endregion #region -------向客户端发送数据块------------------- br.BaseStream.Seek(startBytes, SeekOrigin.Begin); int maxCount = (int)Math.Ceiling((fileLength - startBytes + 0.0) / packSize); //分块下载,剩余部分可分成的块数 for (int i = 0; i < maxCount && context.Response.IsClientConnected; i++) { //客户端中断连接,则暂停 context.Response.BinaryWrite(br.ReadBytes(packSize)); context.Response.Flush(); if (sleep > 1) { Thread.Sleep(sleep); } } #endregion } catch { ret = false; } finally { br.Close(); myFile.Close(); PFDataHelper.DeleteFile(path); } } catch { ret = false; } return(ret); }