如何使用asp.net和c#流式传输Excel 2007或Word 2007文件

13

我正在开发一个Web应用程序,需要流式传输各种文件。我可以流式传输pdf、图像和旧版Office文档。然而,当我尝试使用2007年的文档时,它会出现错误。以下是我的代码:

    Response.Buffer = true;
    Response.Clear();
    Response.ClearContent();
    Response.ClearHeaders();
    switch (FileExtension.ToLower())
    {
        case "pdf":
            Response.ContentType = "application/pdf";
            break;
        case "doc":
            Response.ContentType = "application/msword";
            break;
        case "docx":
            Response.ContentType = "application/vnd.ms-word.document.12";
            break;
        case "xls":
            Response.ContentType = "application/vnd.ms-excel";
            break;
        case "xlsx":
            Response.ContentType = "application/vnd.ms-excel.12";
            break;
        default:
            Response.ContentType = "image/jpeg";
            break;
    }
    Response.BinaryWrite(buffer);

我收到的错误信息是:

在处理 'http://DomainName/GetFile.aspx...' 时发现文本内容中存在无效字符。
PK

有什么建议吗?

3个回答

16
根据简短的网络搜索,Word 和 Excel 的正确 MIME 类型为:
application/vnd.openxmlformats-officedocument.wordprocessingml.document
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

http://www.bram.us/2007/05/25/office-2007-mime-types-for-iis/

编辑:

以下简化示例对我有效。与您的不同之处在于它使用通用处理程序而不是Web表单(这对于此类操作更为适合)。

要测试它,请确保应用程序的顶级文件夹中有一个名为Book1.xlsx的Excel 2007文件。

DownloadSpreadsheet.ashx:

<%@ WebHandler Language="C#" Class="DownloadSpreadsheetHandler" %>

using System;
using System.Web;
using System.IO;

public class DownloadSpreadsheetHandler: IHttpHandler {

    public void ProcessRequest (HttpContext context) {
        context.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        string path = context.Server.MapPath("~/Book1.xlsx");
        using (FileStream spreadsheet = File.OpenRead(path))
        {
            CopyStream(spreadsheet, context.Response.OutputStream);
        }
    }

    public bool IsReusable {
        get {
            return false;
        }
    }

    private static void CopyStream(Stream input, Stream output)
    {
        byte[] buffer = new byte[32768];
        while (true)
        {
            int read = input.Read(buffer, 0, buffer.Length);
            if (read <= 0)
                return;
            output.Write(buffer, 0, read);
        }
    }

}

尝试了一下,效果略有改善。至少弹出了打开/保存/取消对话框。但是,如果我点击docx文件中的“打开”,我什么都看不到,只有一个空的HTML页面。如果我在对话框中选择“保存到文件”然后打开它,我需要点一些错误信息,才能得到正确的文件。对于xlsx文件,如果我先保存再打开,会出现与docx相同的情况,即会弹出几个错误信息,然后才会打开。但是,如果我直接点击xlsx文件中的“打开”,则需要点几次错误信息,才能打开Excel。但是,打开后的数据却是我的登录页面,而非文档内容。 - Kevin
搞定了。为什么它会这样工作而不是另一种方式,我不知道,但我现在太忙了,无暇顾及。 - Kevin
在context.Response上还有一个方便的方法叫做WriteFile,它可以让您避免手动复制文件流。 - Brenner256
还有Response.BinaryWrite(),你可以用File.ReadAllByte(filePath)填充它。这让我跳过了CopyStream循环。 - mrshickadance

5
.doc


application/msword

.dot


application/msword

.docx


application/vnd.openxmlformats-officedocument.wordprocessingml.document

.dotx


application/vnd.openxmlformats-officedocument.wordprocessingml.template

.docm


application/vnd.ms-word.document.macroEnabled.12

.dotm


application/vnd.ms-word.template.macroEnabled.12

.xls


application/vnd.ms-excel

.xlt


application/vnd.ms-excel

.xla


application/vnd.ms-excel

.xlsx


application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

.xltx


application/vnd.openxmlformats-officedocument.spreadsheetml.template

.xlsm


application/vnd.ms-excel.sheet.macroEnabled.12

.xltm


application/vnd.ms-excel.template.macroEnabled.12

.xlam


application/vnd.ms-excel.addin.macroEnabled.12

.xlsb


application/vnd.ms-excel.sheet.binary.macroEnabled.12

.ppt


application/vnd.ms-powerpoint

.pot


application/vnd.ms-powerpoint

.pps


application/vnd.ms-powerpoint

.ppa


application/vnd.ms-powerpoint

.pptx


application/vnd.openxmlformats-officedocument.presentationml.presentation

.potx


application/vnd.openxmlformats-officedocument.presentationml.template

.ppsx


application/vnd.openxmlformats-officedocument.presentationml.slideshow

.ppam


application/vnd.ms-powerpoint.addin.macroEnabled.12

.pptm


application/vnd.ms-powerpoint.presentation.macroEnabled.12

.potm


application/vnd.ms-powerpoint.presentation.macroEnabled.12

.ppsm


application/vnd.ms-powerpoint.slideshow.macroEnabled.12

能否添加您的来源呢?例如:来自维基百科 - Scotty.NET

0
对于我们希望使用Excel打开的csv格式文件,我们使用以下代码:Response.ContentType = "application/msexcel"; 也许这是因为它不是真正的xls文件,所以我们可以这样做。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接