コード例 #1
0
        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);
        }
コード例 #2
0
        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);
        }