none
承蒙上次孟老师指点,从msdn上学习了关于OpenXML的相关知识,导出的Excel不再报“与文件指定的扩展名不一致”的错误,先行感谢。但是现在每次都是导入到D盘,我想实现点击按钮后出现下载对话框的那种效果,希望高手指点 RRS feed

  • 问题

  • 要运行以下代码,需安装OpenXML SDK2.0 下载地址:http://www.microsoft.com/downloads/details.aspx?familyid=c6e744e5-36e9-45f5-8d8c-331df206e0d0&displaylang=en&tm

    然后引用如下命名空间:

    using DocumentFormat.OpenXml;
    using DocumentFormat.OpenXml.Packaging;
    using DocumentFormat.OpenXml.Wordprocessing;

     

    我的问题集中在红色部分

    Code Snippet

    protected void Button1_Click(object sender, EventArgs e)
            {
                File.Copy(Server.MapPath(@"sampledoc/createtable.docx"), Server.MapPath(@"sampledoc/generated.docx"), true);//createtable.docx是一个只有一行字得文档
                using (WordprocessingDocument doc = WordprocessingDocument.Open(Server.MapPath(@"sampledoc/generated.docx"), true))
                {
                    DocumentFormat.OpenXml.Wordprocessing.Table table = new DocumentFormat.OpenXml.Wordprocessing.Table();
                    // Create TableProperties to specify the table border information
                    TableProperties tblProp = new TableProperties(
                        new TableBorders(
                            new TopBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 1 },
                            new BottomBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 1 },
                            new LeftBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 1 },
                            new RightBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 1 },
                            new InsideHorizontalBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 1 },
                            new InsideVerticalBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = 1 }
                        )
                    );
                    table.AppendChild<TableProperties>(tblProp);

                    // Create a header row
                    DocumentFormat.OpenXml.Wordprocessing.TableRow headerRow = new DocumentFormat.OpenXml.Wordprocessing.TableRow();
                    table.AppendChild(headerRow);
                    foreach (DataColumn column in CreateMockDataSet().Tables[0].Columns)
                    {
                        // Create a cell
                        DocumentFormat.OpenXml.Wordprocessing.TableCell tc = new DocumentFormat.OpenXml.Wordprocessing.TableCell();
                        // Specify the table cell property by setting the table cell width to 300 points
                        tc.Append(new TableCellProperties(new TableCellWidth() { Type = TableWidthUnitValues.Dxa, Width = 2400 }));
                        // Set the table cell content
                        tc.Append(new Paragraph(new Run(new Text(column.ColumnName))));
                        headerRow.Append(tc);
                    }

                    // Fill in the data rows
                    foreach (DataRow row in CreateMockDataSet().Tables[0].Rows)
                    {
                        // Create the first row
                        DocumentFormat.OpenXml.Wordprocessing.TableRow tr = new DocumentFormat.OpenXml.Wordprocessing.TableRow();

                        // Create a cell
                        DocumentFormat.OpenXml.Wordprocessing.TableCell tc1 = new DocumentFormat.OpenXml.Wordprocessing.TableCell();
                        // Specify the table cell property by setting the table cell width to 300 points
                        tc1.Append(new TableCellProperties(new TableCellWidth() { Type = TableWidthUnitValues.Dxa, Width = 2400 }));
                        // Set the table cell content
                        tc1.Append(new Paragraph(new Run(new Text(row["DocID"].ToString()))));
                        tr.Append(tc1);

                        // Create the second cell in the row
                        DocumentFormat.OpenXml.Wordprocessing.TableCell tc2 = new DocumentFormat.OpenXml.Wordprocessing.TableCell();
                        // Specify the table cell property by setting the table cell width to 300 points
                        tc2.Append(new TableCellProperties(new TableCellWidth() { Type = TableWidthUnitValues.Dxa, Width = 2400 }));
                        // Set the table cell content
                        tc2.Append(new Paragraph(new Run(new Text(row["DocName"].ToString()))));
                        tr.Append(tc2);

                        // Create the third cell in the row
                        DocumentFormat.OpenXml.Wordprocessing.TableCell tc3 = new DocumentFormat.OpenXml.Wordprocessing.TableCell();
                        // Specify the table cell property by setting the table cell width to 300 points
                        tc3.Append(new TableCellProperties(new TableCellWidth() { Type = TableWidthUnitValues.Dxa, Width = 2400 }));
                        // Set the table cell content
                        tc3.Append(new Paragraph(new Run(new Text(row["ChapterTitle"].ToString()))));
                        tr.Append(tc3);
                        table.AppendChild(tr);
                    }

                    // Append the table to the document
                    doc.MainDocumentPart.Document.Body.Append(table);
                    // Since we changed the MainDocumentPart, we need to save the modification back to the part
                    doc.MainDocumentPart.Document.Save();
                    //在网上狂搜了一天,找到如下代码,但是导出的Excel不能打开,跪求那位高手指点一下
                    System.IO.FileInfo file = new System.IO.FileInfo(Server.MapPath(@"sampledoc/generated.docx"));
                    Response.Clear();
                    Response.ClearHeaders();
                    Response.Buffer = false;
                    Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
                    Response.AddHeader("Content-Disposition", "attachment;filename=" + System.Web.HttpUtility.UrlEncode(@"aa.docx", System.Text.Encoding.UTF8));
                    Response.Charset = "GB2312";
                    Response.ContentEncoding = System.Text.Encoding.UTF8;
                    Response.Write(Server.MapPath(@"sampledoc/generated.docx"));
                    Response.Flush();
                    Response.End();
                }
            }

            private static DataSet CreateMockDataSet()
            {
                DataTable table = new DataTable("sample");

                DataColumn column;
                DataRow row;

                // Create the first column and add to the DataTable.
                column = new DataColumn();
                column.DataType = System.Type.GetType("System.Int32");
                column.ColumnName = "DocID";
                column.AutoIncrement = true;
                column.Caption = "ID";
                // Add the column to the DataColumnCollection.
                table.Columns.Add(column);

                // Create the second column and add it to the column set.
                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "DocName";
                column.AutoIncrement = false;
                column.Caption = "DocName";
                table.Columns.Add(column);

                // Create the third column and add it to the column set.
                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "ChapterTitle";
                column.AutoIncrement = false;
                column.Caption = "ChapterTitle";
                table.Columns.Add(column);

                // Create five DataRow objects, and add them to DataTable.
                for (int i = 0; i <= 4; i++)
                {
                    row = table.NewRow();
                    row["DocID"] = i;
                    row["DocName"] = "Doc " + i;
                    row["ChapterTitle"] = "Chapter Title " + i;
                    table.Rows.Add(row);
                }

                // Create a data set from the table and return it.
                DataSet ds = new DataSet();
                ds.Tables.Add(table);

                return ds;
            }

     

     

    2008年12月31日 15:24

答案

  •  

    Response.Clear();
    Response.ClearHeaders();
    Response.Buffer = false;
    Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
    Response.AddHeader("Content-Disposition", "attachment;filename=" + System.Web.HttpUtility.UrlEncode(@"aa.docx", System.Text.Encoding.UTF8));
    Response.Charset = "GB2312";
    Response.ContentEncoding = System.Text.Encoding.UTF8;
    Response.WriteFile(Server.MapPath(@"sampledoc/generated.docx"));
    Response.Flush();
    Response.End();

     

     

    2009年1月2日 0:15
    版主

全部回复

  • http://forums.microsoft.com/china/ShowPost.aspx?PostID=4259367&SiteID=15

    你上次的帖子还没结贴呢  横横

    mime是

    application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

    有可能直接打开

    如果是

    application/octet-stream

    就只能保存了

    2008年12月31日 23:23
  • 韦兄你好,上次的贴我按照您的说法做了,将扩展名改成xlsx,根本打不开,将扩展名改为xls,则还是出现“与文件指定的扩展名”不一致的错误,不过谢谢您的耐心解答。针对上次的恢复我已经结贴了。麻烦您帮我看看这次的贴,谢谢。

    2009年1月1日 1:37
  • 我在网上搜索了一天,把源代码又改了一下,如果各位看着很乱的话只看红色部分就成了。我实在没招儿了,各位高手帮帮忙吧。

    2009年1月1日 9:20
  • 你要创建xls文档,应该使用SpreadsheetDocument啊,创建的excel文件扩展名是 xlsx ,而不是docx啊。

     

    手头没有office 2007,你可以先参见

    http://msdn.microsoft.com/en-us/library/cc861607(office.14).aspx

     

    http://social.msdn.microsoft.com/Forums/en-US/oxmlsdk/thread/b1f1fdea-996e-4bf4-b650-3bd79b3fa0e9/

     

     

     

    2009年1月1日 10:32
    版主
  • 我好意思,我说错了。应该是导出word文件。

    现在文件我已经导出在@"sampledoc/generated.docx"里面了,只是不知道如何将他输出到客户端

    2009年1月1日 11:30
  •  

    Response.WriteFile(Server.MapPath("~/sampledoc/generated.docx"));

     

    就可以直接输出文件

    2009年1月1日 11:58
    版主
  •  

    孟老师,报了个错:

    文件“d:\Users\杜宏宇\Documents\Visual Studio 2008\Projects\WebApplication1\WebApplication1\sampledoc\generated.docx”正由另一进程使用,因此该进程无法访问该文件。

    2009年1月1日 12:51
  •  杜宏宇 写:

     

    我好意思,我说错了。应该是导出word文件。

    现在文件我已经导出在@"sampledoc/generated.docx"里面了,只是不知道如何将他输出到客户端

     

     

     

    孟老师,报了个错:

    文件“d:\Users\杜宏宇\Documents\Visual Studio 2008\Projects\WebApplication1\WebApplication1\sampledoc\generated.docx”正由另一进程使用,因此该进程无法访问该文件。

     

    说明输出之前没有关闭所有打开这个文件的对象

     

    要么是没有输出完毕 要么是你没关闭文件  要么杀毒软件在扫描

     

    怎么输出的很重要

    简单的方式是用  system.threading.thread.sleep(3000) 等待一下看看会不会释放  就能判断是不是因为没有输出完毕

     

     

    2009年1月1日 14:02
  •  

    不行,加入文件在@"sampledoc/generated.docx"里面。我直接用 Response.WriteFile(@"sampledoc/generated.docx", true);下载默认扩展名是zip,而不是docx
    2009年1月1日 16:07
  •  

    Response.Clear();
    Response.ClearHeaders();
    Response.Buffer = false;
    Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
    Response.AddHeader("Content-Disposition", "attachment;filename=" + System.Web.HttpUtility.UrlEncode(@"aa.docx", System.Text.Encoding.UTF8));
    Response.Charset = "GB2312";
    Response.ContentEncoding = System.Text.Encoding.UTF8;
    Response.WriteFile(Server.MapPath(@"sampledoc/generated.docx"));
    Response.Flush();
    Response.End();

     

     

    2009年1月2日 0:15
    版主
  • 请教孟老师一个问题:

    我在用openxml打开一个excel模板,但是怎么才能向模板里面添加内容呢?
    我在网上找了很多,都是在sheet为空的情况下添加的

    先谢谢了,忘能给点建议

    邮箱:sunjieking@yahoo.com.cn
    QQ:270547430
    2009年9月21日 8:34