【问题标题】:Excel Open XML error: "found unreadable content" when creating simple exampleExcel Open XML 错误:创建简单示例时出现“发现不可读的内容”
【发布时间】:2016-08-30 15:57:10
【问题描述】:

当我尝试打开由以下代码创建的文档时,我收到了模棱两可的“excel 发现不可读的内容”错误:

public void GenerateWorkbookFromDB()
{
    //Make a copy of the template file
    File.Copy(HttpContext.Current.Server.MapPath("ReportTemplate/test.xlsx"), HttpContext.Current.Server.MapPath("Reports/test.xlsx"), true);

    //Open up the copied template workbook
    using (SpreadsheetDocument myWorkbook = SpreadsheetDocument.Open(HttpContext.Current.Server.MapPath("Reports/test.xlsx"), true))
    {
        WorkbookPart workbookPart = myWorkbook.WorkbookPart;
        WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
        string origninalSheetId = workbookPart.GetIdOfPart(worksheetPart);

        WorksheetPart replacementPart = workbookPart.AddNewPart<WorksheetPart>();
        string replacementPartId = workbookPart.GetIdOfPart(replacementPart);

        OpenXmlReader reader = OpenXmlReader.Create(worksheetPart);
        OpenXmlWriter writer = OpenXmlWriter.Create(replacementPart);

        Row r = new Row();
        Cell c = new Cell();
        CellValue v = new CellValue();
        v.Text = "test";
        c.Append(v);

        while (reader.Read())
        {
            if (reader.ElementType == typeof(SheetData))
            {
                if (reader.IsEndElement)
                    continue;
                writer.WriteStartElement(new SheetData());

                for (int row = 0; row < 20; row++)
                {
                    writer.WriteStartElement(r);

                    for (int col = 0; col < 4; col++)
                    {
                        writer.WriteElement(c);
                    }

                    writer.WriteEndElement();
                }

                writer.WriteEndElement();
            }
            else
            {
                if (reader.IsStartElement)
                    writer.WriteStartElement(reader);
                else if (reader.IsEndElement)
                    writer.WriteEndElement();
            }
        }
        reader.Close();
        writer.Close();

        try
        {
            Sheet sheet = workbookPart.Workbook.Descendants<Sheet>().Where(s => s.Id.Value.Equals(origninalSheetId)).First();
            sheet.Id.Value = replacementPartId;
            workbookPart.DeletePart(worksheetPart);
        }
        catch (Exception ex) { }
    }
}

非常感谢任何帮助或建议! :D

【问题讨论】:

  • 你究竟是从哪里得到这个错误的?当您查看 Office Open Xml 工具中的 xlsx 时,该特定位置的 xml 是什么?
  • 当我在调用 GenerateWorkbookFromDB() 后尝试打开文档时,Excel 给了我错误。它让我可以选择通过单击“是”来打开它。我不希望我的应用程序的用户每次都必须点击它:D

标签: c# asp.net excel openxml openxml-sdk


【解决方案1】:

我实际上找到了一种通过更改将文本输入到单元格本身的方式来修复错误的方法。请注意,在下面的代码中,我注释掉了 2 行以及替换它们的内容。

public void GenerateWorkbookFromDB()
{
    //Make a copy of the template file
    File.Copy(HttpContext.Current.Server.MapPath("ReportTemplate/test.xlsx"), HttpContext.Current.Server.MapPath("Reports/test.xlsx"), true);

    //Open up the copied template workbook
    using (SpreadsheetDocument myWorkbook = SpreadsheetDocument.Open(HttpContext.Current.Server.MapPath("Reports/test.xlsx"), true))
    {
        WorkbookPart workbookPart = myWorkbook.WorkbookPart;
        WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
        string origninalSheetId = workbookPart.GetIdOfPart(worksheetPart);

        WorksheetPart replacementPart = workbookPart.AddNewPart<WorksheetPart>();
        string replacementPartId = workbookPart.GetIdOfPart(replacementPart);

        OpenXmlReader reader = OpenXmlReader.Create(worksheetPart);
        OpenXmlWriter writer = OpenXmlWriter.Create(replacementPart);

        Row r = new Row();
        Cell c = new Cell();
        string txt = "test";
        c.CellValue = new CellValue(txt.ToString());
        c.DataType = new EnumValue<CellValues>(CellValues.String);
        //v.Text = "test";
        //c.Append(v);

        while (reader.Read())
        {
            if (reader.ElementType == typeof(SheetData))
            {
                if (reader.IsEndElement)
                    continue;
                writer.WriteStartElement(new SheetData());

                for (int row = 0; row < 20; row++)
                {
                    writer.WriteStartElement(r);

                    for (int col = 0; col < 4; col++)
                    {
                        writer.WriteElement(c);
                    }

                    writer.WriteEndElement();
                }

                writer.WriteEndElement();
            }
            else
            {
                if (reader.IsStartElement)
                    writer.WriteStartElement(reader);
                else if (reader.IsEndElement)
                    writer.WriteEndElement();
            }
        }
        reader.Close();
        writer.Close();

        try
        {
            Sheet sheet = workbookPart.Workbook.Descendants<Sheet>().Where(s => s.Id.Value.Equals(origninalSheetId)).First();
            sheet.Id.Value = replacementPartId;
            workbookPart.DeletePart(worksheetPart);
        }
        catch (Exception ex) { }
    }
}

我希望这对可能遇到相同问题或类似问题的其他人有所帮助。

感谢那些试图回答的人;-)

【讨论】:

  • 为此找了好久,Daniel 欢呼,我的团队负责人对我很生气 :( 但我很高兴我找到了这个
  • 知道如何解决此答案的错误:stackoverflow.com/questions/19529436/…... 虽然当我单击“是”打开文件时,一切都保持原样,但我无法对文件。
【解决方案2】:

我希望它可能对某人有用。

我收到了同样的错误消息,在我的情况下,原因是工作表的名称太长。

Excel 不断将其截断为 31 个字符。因此,一旦我将在代码中分配的工作表名称限制为 31 个字符,问题就解决了。

【讨论】:

  • 非常感谢您指出这一点,为我节省了至少一个小时或更长时间。
【解决方案3】:

我发现,您需要确保在将 Cell 对象添加到行集合时,以正确的顺序放置它们。它们的出现顺序必须与它们在电子表格中显示的顺序相同。例如A2,B2,C2 ... Z2,AA2,AB2。请注意,如果您尝试比较列的值来放置它们,它们将在 A2 和 B2 之间使用 AA2 排序,这将导致您尝试打开工作表时出错。

【讨论】:

    【解决方案4】:

    我通过在 Cell 上设置正确的类型来纠正它。例如,就我而言,我有两种类型的值:数字和字符串。

     public static void WriteValueOnCell(Cell cell, object value)
        {
            var sValue = value = x.ToString();
            var isValueNumeric = value.GetType().IsNumeric();
            cell.DataType = (isValueNumeric)? CellValues.Number : CellValues.String;
            cell.CellValue = new CellValue(sValue);
        }
        //This example uses this Helper. It informs if an object type is Numeric ;-)
        public static class TypeHelper
        {
            private static readonly HashSet<Type> NumericTypes = new HashSet<Type>
            {
                typeof(int),  typeof(double),  typeof(decimal),
                typeof(long), typeof(short),   typeof(sbyte),
                typeof(byte), typeof(ulong),   typeof(ushort),
                typeof(uint), typeof(float)
            };
    
            public static bool IsNumeric(this Type myType)
            {
                return NumericTypes.Contains(Nullable.GetUnderlyingType(myType) ?? myType);
            }
        }
    

    【讨论】:

    【解决方案5】:

    在工作簿中,数据字段中是否保留了任何字符?例如''?我已经看到 XML 解析会发生这种情况,因此它可能是非法字符。我不知道您的情况是否允许,但 HTTPUtility.HTMLEncode 会起作用吗?

    【讨论】:

    • 它正在复制并放入所有内容的工作簿来自一个空白模板。除了“测试”之外,我看不到任何东西会被放入任何单元格中。
    • 不错的丹尼尔。我也不知道,我只是在 XML 方面摸不着头脑。
    【解决方案6】:

    对我有用的是修改 web.config 文件。

    我输入了一个 maxRequestLength 和 executionTimeout,之后它运行良好!

    在 System.Web 下,放置以下内容:

    httpRuntime requestValidationMode="2.0" maxRequestLength="1048576" executionTimeout="600"
    

    试试看是否有帮助。

    【讨论】:

      【解决方案7】:

      我遇到了这个问题,在使用 SDK 工具后,我发现 CellValues.Date 实际上不受支持。如果您尝试将单元格格式化为具有适当的 DataType 并且收到此消息,请尝试将日期单元格保留为 CellValues.String。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多