C#用COM导出Excel时,Excel不保存在服务器上,用Session保存Excel内容,直接给客户端下载

时间:2021-12-07 17:51:59
 Excel.Application myExcel = new Excel.Application();
   myExcel.Visible =false;         
  myExcel.DisplayAlerts = false;
    _Workbook myBook;
        myBook = myExcel.Workbooks.Add(true);
           _Worksheet mySheet; //9-30
            mySheet= (_Worksheet)myBook.ActiveSheet; 
  Excel.Range r = (Range)mySheet.get_Range("A1", "M35");
   r.HorizontalAlignment = XlHAlign.xlHAlignCenter;  //设置字体在单元格内的对齐方式
  r.EntireColumn.AutoFit();   //自动调整列宽
   r.WrapText = true;      //文本自动换行
    r.Borders.LineStyle = 1;
                 。。。Excel的赋值等。。。。
 session["DownloadFile"]=myExcel;
 myBook.Close(false, null, false);
            System.Runtime.InteropServices.Marshal.ReleaseComObject(myBook);            
     myBook = null;
            System.Runtime.InteropServices.Marshal.ReleaseComObject(myExcel); 
            mySheet = null;
            //myExcel.Quit();
            myExcel = null;
            GC.Collect();
在下载页面:
Excel.Application file = (Excel.Application)Session["DownloadFile"];
 Response.Clear();
Response.ClearContent();
        Response.Buffer = true;
        Response.Charset = "GB2312";
        Response.ContentType = "application/octet-stream";
        Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlPathEncode(filename));
        Response.ContentEncoding = System.Text.Encoding.Default;
        Response.ContentType = "application/ms-excel";
        Response.Output.Write(file);
        Response.Flush();
        Response.End();
为什么下载的Excel内容是 Excel.ApplicationClass 而不是正确的Excel文件内容

17 个解决方案

#1


把Excel.Application对象放到session里当然不对。

Excel没有保存到内存的功能,只能保存到文件。需要有个临时文件,让excel保存到临时文件,然后读临时文件到内存,放到session里,再删掉临时文件。(不知道这样保存到session里还有没有意义了...)

#2


Excel.Application对象放到session里主要是为了不在服务器端生成Excel文件。。。。

#3


额,Excel.Application这东西我印象中没有save2Stream 功能,所以你只能先存临时文件,然后在读出stream

ps:在csdn下载频道输入aspose.cell你可以找到更容易的东西,当然他是可以输出成stream滴

#4


难道只有先存临时文件,再读出这种方法吗?没有直接把Excel文件提供客户端的吗?因为表格很复杂,如果重新在用其他的方法的话,就太麻烦了,又要重新设置格式。。。

#5


重新设置格式??设置什么格式?
你就是把保存到session简单的修改为saveAs(路径)
然后将文件下载到客户端,不就完了
生成excel的部分完全不需要任何改动

#6


文件名用系统时间取名,保证不重复,下载完删除,不就得了,纠结什么服务器上不要放文件,这个没有意义

#7


Excel.Application myExcel = new Excel.Application();
   myExcel.Visible =false;         
  myExcel.DisplayAlerts = false;
    _Workbook myBook;
        myBook = myExcel.Workbooks.Add(true);
           _Worksheet mySheet; //9-30
            mySheet= (_Worksheet)myBook.ActiveSheet; 
  Excel.Range r = (Range)mySheet.get_Range("A1", "M35");
   r.HorizontalAlignment = XlHAlign.xlHAlignCenter;  //设置字体在单元格内的对齐方式
  r.EntireColumn.AutoFit();   //自动调整列宽
   r.WrapText = true;      //文本自动换行
    r.Borders.LineStyle = 1;
                 。。。Excel的赋值等。。。。
 myBook.SaveAs(Server.MapPath(filename));//修改为Saveas
 myBook.Close(false, null, false);
            System.Runtime.InteropServices.Marshal.ReleaseComObject(myBook);            
     myBook = null;
            System.Runtime.InteropServices.Marshal.ReleaseComObject(myExcel); 
            mySheet = null;
            //myExcel.Quit();
            myExcel = null;
            GC.Collect();
下载页面:
       System.IO.FileStream fileResult = System.IO.File.OpenRead(filepath);
        byte[] buffer = new byte[fileResult.Length];
        fileResult.Read(buffer, 0, buffer.Length);
        fileResult.Close();
       File.Delete(filepath);//这句话加入就会出现找不到文件,如果没有这句就导出成功
        Response.Clear();
        Response.ClearContent();
        Response.Buffer = true;
        Response.Charset = "GB2312";
        Response.ContentEncoding = System.Text.Encoding.UTF8;
        Response.ContentType = "application/octet-stream";
        Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlPathEncode(name));
        Response.ContentEncoding = System.Text.Encoding.Default;
        Response.OutputStream.Write(buffer,0,buffer.Length);
        fileResult.Close();
       // System.IO.File.Delete(filepath);//这句话加入就会出现找不到文件,如果没有这句就导出成功。
        Response.Flush();
        Response.End();

#8


现在如果没有 File.Delete(filepath);//这句话  把程序发布到服务器,点击导出按钮没反应。。。在本地测试是可以的。。。各位大神可以帮帮忙解决一下吗?非常感谢!

#9


引用 8 楼 q876959260 的回复:
现在如果没有 File.Delete(filepath);//这句话  把程序发布到服务器,点击导出按钮没反应。。。在本地测试是可以的。。。各位大神可以帮帮忙解决一下吗?非常感谢!

服务器com和iis权限要配置,自己搜去吧,比较复杂,无数问题。

#10


File.Delete(filepath);//这句话加入就会出现找不到文件,如果没有这句就导出成功
废话吗,你先把saveAs的文件删除了,还下载什么啊
如何从服务器下载文件到客户端,这个代码很简单,不要拍脑袋想,把文件流来回转没什么意义


    void downloadfile(string s_path)
    {
        System.IO.FileInfo file = new System.IO.FileInfo(s_path);
        HttpContext.Current.Response.ContentType = "application/ms-download";
        HttpContext.Current.Response.Clear();
        HttpContext.Current.Response.AddHeader("Content-Type", "application/octet-stream");
        HttpContext.Current.Response.Charset = "utf-8";
        HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=" + System.Web.HttpUtility.UrlEncode(file.Name, System.Text.Encoding.UTF8));
        HttpContext.Current.Response.AddHeader("Content-Length", file.Length.ToString());
        HttpContext.Current.Response.WriteFile(file.FullName);
        HttpContext.Current.Response.Flush();
        HttpContext.Current.Response.Clear();
        HttpContext.Current.Response.End();
    }

#11


我主要是想下载后把服务器的文件删除的。。。。

#12


引用 11 楼 q876959260 的回复:
我主要是想下载后把服务器的文件删除的。。。。

为什么要删?
你如何确定用户已经下载过了?

#13


引用 12 楼 yuwenge 的回复:
Quote: 引用 11 楼 q876959260 的回复:

我主要是想下载后把服务器的文件删除的。。。。

为什么要删?
你如何确定用户已经下载过了?

正确的做法是:

string fileName = DateTime.Now.ToString("MMdd_HHmmss") + "_XXXX.xlsx";
string excelpath = Server.MapPath("..") + Tools.GetDownloadDir(); //获取存放excel目录

用系统时间命名文件,保存Excel到临时目录。
定期清理临时文件夹。

#14


引用 11 楼 q876959260 的回复:
我主要是想下载后把服务器的文件删除的。。。。

最简单有效不冲突的办法
每个用户最初登陆的时候,代码自动按用户名生成个文件夹
导入导出,上传下载,文件都放到用户自己的目录里去
等他下次登陆,删掉文件夹,重新建一个同名文件夹

#15


不要所有用户公用一个临时文件夹,定期清理的时候很可能人家操作一半,你就给清理了,导致上传下载不成功

#16


引用 9 楼 yuwenge 的回复:
Quote: 引用 8 楼 q876959260 的回复:

现在如果没有 File.Delete(filepath);//这句话  把程序发布到服务器,点击导出按钮没反应。。。在本地测试是可以的。。。各位大神可以帮帮忙解决一下吗?非常感谢!

服务器com和iis权限要配置,自己搜去吧,比较复杂,无数问题。


真的是Com权限配置有问题。。。现在已经解决了!谢了!

#17


引用 15 楼 Z65443344 的回复:
不要所有用户公用一个临时文件夹,定期清理的时候很可能人家操作一半,你就给清理了,导致上传下载不成功

清理文件是自己清理的吗?我有次试验是成功的,下载后服务器端没有文件了。。。但是代码被我改来改去不记得了。。。现在试了好多次都没有成功。。。

#1


把Excel.Application对象放到session里当然不对。

Excel没有保存到内存的功能,只能保存到文件。需要有个临时文件,让excel保存到临时文件,然后读临时文件到内存,放到session里,再删掉临时文件。(不知道这样保存到session里还有没有意义了...)

#2


Excel.Application对象放到session里主要是为了不在服务器端生成Excel文件。。。。

#3


额,Excel.Application这东西我印象中没有save2Stream 功能,所以你只能先存临时文件,然后在读出stream

ps:在csdn下载频道输入aspose.cell你可以找到更容易的东西,当然他是可以输出成stream滴

#4


难道只有先存临时文件,再读出这种方法吗?没有直接把Excel文件提供客户端的吗?因为表格很复杂,如果重新在用其他的方法的话,就太麻烦了,又要重新设置格式。。。

#5


重新设置格式??设置什么格式?
你就是把保存到session简单的修改为saveAs(路径)
然后将文件下载到客户端,不就完了
生成excel的部分完全不需要任何改动

#6


文件名用系统时间取名,保证不重复,下载完删除,不就得了,纠结什么服务器上不要放文件,这个没有意义

#7


Excel.Application myExcel = new Excel.Application();
   myExcel.Visible =false;         
  myExcel.DisplayAlerts = false;
    _Workbook myBook;
        myBook = myExcel.Workbooks.Add(true);
           _Worksheet mySheet; //9-30
            mySheet= (_Worksheet)myBook.ActiveSheet; 
  Excel.Range r = (Range)mySheet.get_Range("A1", "M35");
   r.HorizontalAlignment = XlHAlign.xlHAlignCenter;  //设置字体在单元格内的对齐方式
  r.EntireColumn.AutoFit();   //自动调整列宽
   r.WrapText = true;      //文本自动换行
    r.Borders.LineStyle = 1;
                 。。。Excel的赋值等。。。。
 myBook.SaveAs(Server.MapPath(filename));//修改为Saveas
 myBook.Close(false, null, false);
            System.Runtime.InteropServices.Marshal.ReleaseComObject(myBook);            
     myBook = null;
            System.Runtime.InteropServices.Marshal.ReleaseComObject(myExcel); 
            mySheet = null;
            //myExcel.Quit();
            myExcel = null;
            GC.Collect();
下载页面:
       System.IO.FileStream fileResult = System.IO.File.OpenRead(filepath);
        byte[] buffer = new byte[fileResult.Length];
        fileResult.Read(buffer, 0, buffer.Length);
        fileResult.Close();
       File.Delete(filepath);//这句话加入就会出现找不到文件,如果没有这句就导出成功
        Response.Clear();
        Response.ClearContent();
        Response.Buffer = true;
        Response.Charset = "GB2312";
        Response.ContentEncoding = System.Text.Encoding.UTF8;
        Response.ContentType = "application/octet-stream";
        Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlPathEncode(name));
        Response.ContentEncoding = System.Text.Encoding.Default;
        Response.OutputStream.Write(buffer,0,buffer.Length);
        fileResult.Close();
       // System.IO.File.Delete(filepath);//这句话加入就会出现找不到文件,如果没有这句就导出成功。
        Response.Flush();
        Response.End();

#8


现在如果没有 File.Delete(filepath);//这句话  把程序发布到服务器,点击导出按钮没反应。。。在本地测试是可以的。。。各位大神可以帮帮忙解决一下吗?非常感谢!

#9


引用 8 楼 q876959260 的回复:
现在如果没有 File.Delete(filepath);//这句话  把程序发布到服务器,点击导出按钮没反应。。。在本地测试是可以的。。。各位大神可以帮帮忙解决一下吗?非常感谢!

服务器com和iis权限要配置,自己搜去吧,比较复杂,无数问题。

#10


File.Delete(filepath);//这句话加入就会出现找不到文件,如果没有这句就导出成功
废话吗,你先把saveAs的文件删除了,还下载什么啊
如何从服务器下载文件到客户端,这个代码很简单,不要拍脑袋想,把文件流来回转没什么意义


    void downloadfile(string s_path)
    {
        System.IO.FileInfo file = new System.IO.FileInfo(s_path);
        HttpContext.Current.Response.ContentType = "application/ms-download";
        HttpContext.Current.Response.Clear();
        HttpContext.Current.Response.AddHeader("Content-Type", "application/octet-stream");
        HttpContext.Current.Response.Charset = "utf-8";
        HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=" + System.Web.HttpUtility.UrlEncode(file.Name, System.Text.Encoding.UTF8));
        HttpContext.Current.Response.AddHeader("Content-Length", file.Length.ToString());
        HttpContext.Current.Response.WriteFile(file.FullName);
        HttpContext.Current.Response.Flush();
        HttpContext.Current.Response.Clear();
        HttpContext.Current.Response.End();
    }

#11


我主要是想下载后把服务器的文件删除的。。。。

#12


引用 11 楼 q876959260 的回复:
我主要是想下载后把服务器的文件删除的。。。。

为什么要删?
你如何确定用户已经下载过了?

#13


引用 12 楼 yuwenge 的回复:
Quote: 引用 11 楼 q876959260 的回复:

我主要是想下载后把服务器的文件删除的。。。。

为什么要删?
你如何确定用户已经下载过了?

正确的做法是:

string fileName = DateTime.Now.ToString("MMdd_HHmmss") + "_XXXX.xlsx";
string excelpath = Server.MapPath("..") + Tools.GetDownloadDir(); //获取存放excel目录

用系统时间命名文件,保存Excel到临时目录。
定期清理临时文件夹。

#14


引用 11 楼 q876959260 的回复:
我主要是想下载后把服务器的文件删除的。。。。

最简单有效不冲突的办法
每个用户最初登陆的时候,代码自动按用户名生成个文件夹
导入导出,上传下载,文件都放到用户自己的目录里去
等他下次登陆,删掉文件夹,重新建一个同名文件夹

#15


不要所有用户公用一个临时文件夹,定期清理的时候很可能人家操作一半,你就给清理了,导致上传下载不成功

#16


引用 9 楼 yuwenge 的回复:
Quote: 引用 8 楼 q876959260 的回复:

现在如果没有 File.Delete(filepath);//这句话  把程序发布到服务器,点击导出按钮没反应。。。在本地测试是可以的。。。各位大神可以帮帮忙解决一下吗?非常感谢!

服务器com和iis权限要配置,自己搜去吧,比较复杂,无数问题。


真的是Com权限配置有问题。。。现在已经解决了!谢了!

#17


引用 15 楼 Z65443344 的回复:
不要所有用户公用一个临时文件夹,定期清理的时候很可能人家操作一半,你就给清理了,导致上传下载不成功

清理文件是自己清理的吗?我有次试验是成功的,下载后服务器端没有文件了。。。但是代码被我改来改去不记得了。。。现在试了好多次都没有成功。。。