Ошибка Excel Open XML: «обнаружен нечитаемый контент» при создании простого примера - PullRequest
5 голосов
/ 16 мая 2011

При попытке открыть документ, созданный с помощью следующего кода, я получаю неоднозначную ошибку «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

Ответы [ 7 ]

11 голосов
/ 17 мая 2011

Я действительно нашел способ исправить ошибку, изменив способ ввода текста в саму ячейку.Обратите внимание на приведенный ниже код, где я закомментировал 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) { }
    }
}

Я надеюсь, что это поможет всем, кто может столкнуться с той же проблемой или чем-то подобным.* Спасибо тем, кто пытался ответить; -)

5 голосов
/ 05 июля 2012

Надеюсь, это кому-нибудь пригодится.

Я получил то же сообщение об ошибке, и в моем случае причиной оказалось слишком длинное имя листа.

Excel продолжал сокращать его до 31 символа. Поэтому, как только я ограничил имя рабочего листа, которое я назначил в коде, 31 символом, проблема была решена.

3 голосов
/ 16 мая 2012

Я обнаружил, что вам нужно убедиться, что при добавлении объектов Cell в коллекцию строк вы размещаете их в правильном порядке. Они должны отображаться в том же порядке, что и в электронной таблице. например A2, B2, C2 ... Z2, AA2, AB2. Обратите внимание, что если вы попытаетесь сравнить значения столбцов, чтобы разместить их, они будут отсортированы с AA2 между A2 и B2, что приведет к ошибке, при которой вы пытаетесь открыть лист.

1 голос
/ 30 августа 2016

Я исправил это, установив правильный тип в ячейке.Например, в моем случае у меня есть два типа значений: числовые и строковые.

 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);
        }
    }
0 голосов
/ 03 апреля 2013

У меня была эта проблема, и после использования инструмента SDK я обнаружил, что CellValues.Date фактически не поддерживается. Если вы пытаетесь отформатировать ваши ячейки, чтобы иметь соответствующий тип данных, и вы получаете это сообщение, попробуйте оставить ваши ячейки даты как CellValues.String.

0 голосов
/ 18 апреля 2012

Для меня сработало изменение файла web.config.

Я вставил maxRequestLength и executeTimeout, и после этого он работал нормально!

в System.Web, добавьте следующее:

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

Попробуйте и посмотрите, поможет ли это.

0 голосов
/ 16 мая 2011

в книге, есть ли символы, зарезервированные в полях данных?такие как «<» или «>»?Я видел, как это происходит при разборе XML, поэтому это может быть недопустимый символ.Я не знаю, позволяют ли это ваши обстоятельства, но сработает ли HTTPUtility.HTMLEncode?

...