0

所以在我们的网站上,我们有多个可以下载为 Excel 电子表格的报告,我们通过从硬盘读取空白模板文件,将其复制到 MemoryStream 中,然后使用 DocumentFormat.OpenXml.Spreadsheet 将数据推送到模板中来完成此操作; 然后我们将 MemoryStream 传递给一个函数,该函数设置标头并将流复制到响应中。

在 FF 和 Chrome 中运行良好,但 IE9(和 8,所以我的 QA 告诉我)随机弹出一个 Windows 安全登录对话框,要求您登录远程服务器。我可以取消对话框,或者点击确定(凭据似乎被忽略),然后按预期获取 Excel 文件。查看查询(使用 CharlesProxy)我无法弹出登录对话框,直到我再次禁用 CharlesProxy,所以我看不到我的开发机器和服务器之间的流量是否有任何差异。从我的本地主机(仅从开发/测试服务器)运行调试时也不会发生这种情况。

任何帮助都会很有用,有问题的代码如下。这是从后面代码中的服务器端函数调用的,因此 RespondAsExcel 会清除响应并改为放入 xlsx。

            using (MemoryStream excelStream = new MemoryStream())
    {
        using (FileStream template = new FileStream(Server.MapPath(@"Reports\AlignedTemplateRII.xlsx"), FileMode.Open, FileAccess.Read))
        {
            Master.CopyStream(template, excelStream);
        }

    //Logic here to push data into the Memory stream using DocumentFormat.OpenXml.Spreadsheet;


        Master.RespondAsExcel(excelStream, pgmName);
    }


        public void RespondAsExcel(MemoryStream excelStream, string fileName)
{
    var contenttype = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
    Response.Clear();
    Response.ContentType = contenttype;
    fileName = Utils.ReplaceWhiteSpaceWithUnderScores(fileName);
    Response.AddHeader("content-disposition", "inline;filename=" + fileName);
    Response.Cache.SetCacheability(HttpCacheability.NoCache);

    Response.BinaryWrite(excelStream.ToArray());
    //If that doesn't work, can try this way:
    //excelStream.WriteTo(Response.OutputStream);

    Response.End();
}

        public void CopyStream(Stream source, Stream destination)
{
    byte[] buffer = new byte[32768];
    int bytesRead;
    do
    {
        bytesRead = source.Read(buffer, 0, buffer.Length);
        destination.Write(buffer, 0, bytesRead);
    } while (bytesRead != 0);
}
4

3 回答 3

0

关于总是可以忽略的“额外身份验证对话框”的一些想法浮现在脑海中......不会保证这是你的问题,但它确实闻起来像它的堂兄。

Office 2007 和更高版本的文档使用 WebClient 库打开基于 HTTP 的存储库,这些库在发出请求时不支持任何 IE 的安全区域过滤器。如果文件由 IE 请求,并且主机 URL 包含点(暗示 FQDN),即使该站点是匿名身份验证的(不需要凭据),您也会得到可以取消或只需单击三下的“凭据”对话框并丢弃。昨天我正在处理这个问题,据我所知,如果文件是随 IE 一起交付的,则没有解决方法。IE 传递文件的方式有些怪异,这使得 Office 应用程序认为它必须在打开请求之前对其进行身份验证,即使文件已经传递给客户端!

如果文档是从与请求服务器在同一域中的主机服务器传送的,例如 some-server.a.domain.com 到 my-machine.a.domain.com,则可以克服对话问题。

第二个想法完全源于我自己的经验——openoffice 供应商格式类型有时会在文档流情况下引入它们自己的一套奇怪的东西。我们刚刚使用了一种类型的 application/vnd.ms-excel,虽然它似乎应该映射到相同的应用程序,但问题似乎并不普遍。

也许这可以给你一些关于前进的想法。最终,现在,我认为您遇到的情况没有理想的解决方案。我们在同一条船上,不得不告诉我们获得对话框的内部客户只需点击“取消”,他们就会得到他们想要的文档。

于 2012-04-21T22:42:42.657 回答
0

在您的 RespondAsExcel() 方法中,将您的content-dispositon响应标头从更改inlineattachment。这将强制浏览器以只读方式打开文件。请参阅KB899927

Response.AddHeader("content-disposition", "attachment;filename=" + fileName);
于 2014-08-08T17:21:05.433 回答
0

使用“Response.ContentType="application/vnd.ms-excel"时,我与 VBScript 有类似的情况。我只是添加了以下代码,Windows 安全弹出窗口不再出现:

Response.AddHeader "content-disposition","attachment; filename=your_file_name_here.xls"
于 2017-02-04T03:31:14.877 回答