У меня была такая же проблема с Excel, использующим создание документа OpenXML в C #.
При экспорте документа с плохим ASCII-символом функция экспорта в Excel перестает работать.
Каким-то образом в строковых данных в базе данных моей компании есть причудливые символы.
Несмотря на то, что я использовал сборку Microsoft DocumentFormat.OpenXML из их OpenXML SDK 2.0, он все равно не учитывал это при назначении строковых значений с использованием их объектов.
Исправление:
t.Text = Regex.Replace(sValue, @"[\x00-\x08]|[\x0B\x0C]|[\x0E-\x19]|[\uD800-\uDFFF]|[\uFFFE\uFFFF]", "?");
Это очищает строку sValue, удаляя оскорбительные символы и заменяя их знаком вопроса. Вы можете заменить любую строку или просто использовать пустую строку.
XML-спецификация допускает 0x09 (TAB), 0x0A (LF - перевод строки или NL - новая строка) и 0x0D (CR - возврат каретки). RegEx выше заботится, чтобы не удалить их.
Спецификация XML 1.1 позволяет вам экранировать некоторые из этих символов.
Например: использование & # x03; для 0x03 отображается как & # x03; в HTML и как L в документах Office и блокноте.
Я использую Asp.net, и это автоматически решается в моем GridView, поэтому мне не нужно заменять эти значения - но я полагаю, что это может быть браузер, который позаботится об этом, насколько мне известно.
Я думал об экранировании этих значений в OpenXML, но когда я посмотрел на вывод, он показал разметку excape. Так что Майк & # x03; TeeVee по-прежнему отображается как Майк & # x03; TeeVee в Excel, а не как Майк & # x03; TeeVee или Майк L TeeVee. Вот почему я предпочел подход Mike? TeeVee.
Моя догадка - это ошибка в текущем OpenXML, которая кодирует разрешенные символы XML ASCII, но позволяет проскальзывать неподдерживаемым символам ASCII.
UPDATE:
Я забыл, что могу посмотреть, как отображаются эти символы, с помощью инструмента повышения производительности Open XML SDK 2.0 , чтобы просмотреть документы, такие как Excel.
Там я обнаружил, что он использует формат: _ x0000 _
Помните: XML 1.0 не поддерживает экранирование этих значений, но XML 1.1 поддерживает, поэтому, если вы используете 1.1, вы можете использовать этот код для экранирования.
Обычный XML 1.1 Escape:
t.Text = Regex.Replace(s, @"[\x00-\x08]|[\x0B\x0C]|[\x0E-\x19]|[\uD800-\uDFFF]|[\uFFFE\uFFFF]",
delegate(Match m)
{
return (byte)(m.Value[0]) == 0 //0x00 is not Supported in 1.0 or 1.1
? ""
: ("&#x" + string.Format("{0:00}", (byte)(m.Value[0])) + ";");
});
Если вы экранируете строки для OpenXML, используйте вместо этого:
t.Text = Regex.Replace(s, @"[\x00-\x08]|[\x0B\x0C]|[\x0E-\x19]|[\uD800-\uDFFF]|[\uFFFE\uFFFF]",
delegate(Match m)
{
return (byte)(m.Value[0]) == 0 //0x00 is not Supported in 1.0 or 1.1
? ""
: ("_x" + string.Format("{0:0000}", (byte)(m.Value[0])) + "_");
});