2016-11-30 8 views
0

Что я делаю: populate & формат файла Excel с использованием комбинации Interop и ClosedXML.Excel Interop Открыть/Восстановить исключение HResult

Во-первых, файл заполняется через Interop, затем сохраняется, закрывается, а затем форматирует RichText ячейки с помощью ClosedXML.

К сожалению, это форматирование заставляет Excel просматривать мой файл как «поврежденный» и его необходимо восстановить. Это соответствующая часть:

var workbook = new XLWorkbook(xlsPath); 
var sheet = workbook.Worksheet("Error Log"); 
for (var rownum = 2; rownum <= 10000; rownum++) 
{ 
    var oldcell = sheet.Cell("C" + rownum); 
    var newcell = sheet.Cell("D" + rownum); 
    var oldtext = oldcell.GetFormattedString(); 
    if(string.IsNullOrEmpty(oldtext.Trim())) 
     break; 
    XlHelper.ColorCellText(oldcell, "del", System.Drawing.Color.Red); 
    XlHelper.ColorCellText(newcell, "add", System.Drawing.Color.Green); 
} 
workbook.Save(); 

И метод окраски:

public static void ColorCellText(IXLCell cel, string tagName, System.Drawing.Color col) 
{ 
    var rex = new Regex("\\<g\\sid\\=[\\sa-z0-9\\.\\:\\=\\\"]+?\\>"); 
    var txt = cel.GetFormattedString(); 
    var mc = rex.Matches(txt); 
    var xlcol = XLColor.FromColor(col); 

    foreach (Match m in mc) 
    { 
     txt = txt.Replace(m.Value, ""); 
     txt = txt.Replace("</g>", ""); 
    } 

    var startTag = string.Format("[{0}]", tagName); 
    var endTag = string.Format("[/{0}]", tagName); 

    var crt = cel.RichText; 
    crt.ClearText(); 
    while (txt.Contains(startTag) || txt.Contains(endTag)) 
    { 
     var pos1 = txt.IndexOf(startTag); 
     if (pos1 == -1) 
      pos1 = 0; 
     var pos2 = txt.IndexOf(endTag); 
     if (pos2 == -1) 
      pos2 = txt.Length - 1; 

     var txtLen = pos2 - pos1 - 5; 
     crt.AddText(txt.Substring(0, pos1)); 
     crt.AddText(txt.Substring(pos1 + 5, txtLen)).SetFontColor(xlcol); 
     txt = txt.Substring(pos2 + 6); 
    } 
    if (!string.IsNullOrEmpty(txt)) 
     crt.AddText(txt); 
} 

Ошибка в файле myfile.xlsx были выполнены
следующие ремонтные работы: _x000d__x000a__x000d__x000a_
Восстановленные записи:
строковые свойства /xl/sharedStrings.xml-Part (строки)

Я прошел через все xmls, ищущие подсказки. В затронутом листе, в сравнении с инструментом Productivity Tool, некоторые блоки отображаются как вставленные в восстановленный файл и удаленные в коррумпированном, хотя ничего существенного не изменилось - кроме одного: атрибут стиля этой ячейки. Вот пример:

<x:c r="AA2" s="59"> 
    <x:f> 
    (IFERROR(VLOOKUP(G2,Legende!$A$42:$B$45,2,FALSE),0)) 
    </x:f> 
    </x:c> 

Я проверил styles.xml для стиля 59, но его нет. В восстановленном файле этот стиль был изменен на 14, что в моем styles.xml указано как числовой формат.

К сожалению, глобальный поиск и замена этих индексов недействительного стиля не помогли решить проблему. Видя все происходящее здесь с коррумпированными индексами, переименованными xmls, недопустимыми именованными диапазонами и т. Д., Я выбрал другой маршрут: не использовать interop вообще, возможно, коррупция была вызвана Excel в первую очередь, а раскраска была только Последняя капля.

Использование ClosedXml только:

Wow. Просто вау. Это еще хуже. Я прокомментировал раскраску, так как без этого Interop выпустил читаемый файл без ошибок, так что я тоже ожидаю от ClosedXml.

Это, как я открыть файл и адреса рабочего листа с ClosedXml:

var wb= new XLWorkbook(xlsPath); 
var errors = wb.Worksheet("Error Log"); 

Это, как я пишу значение в файл:

errors.Cell(zeile, 1).SetValue(fname); 

С Зейлем будучи простым ИНТОМ счетчик ,

я тогда осмелился установить ширину столбца:

errors.Column(2).Width = 50; 
errors.Column(3).Width = 50; 
errors.Column(4).Width = 50; 

А также установить некоторые значения в другом листе точно таким же образом, перед сохранением с проверкой.

wb.Save(true); 
wb.Dispose(); 

Глядь: Проверка бросает ошибку:

'имя' атрибута должны иметь уникальное значение. Его текущее значение «Легенд» дублирует с другими.
Атрибут 'sheetId' должен иметь уникальное значение. Его текущее значение «4» дублируется с другими.

Еще пара ошибок, таких как атрибут 'top' с недопустимым значением '11 .425781 '.

Excel не может открыть файл напрямую, его необходимо отремонтировать. Мой лист «Legende» теперь пуст, а первый лист вместо третьего, и я получаю дополнительный четвертый лист «Restored_Table1», который содержит мое оригинальное содержимое «Legende».

Что, черт возьми, происходит с этим файлом ??

Новая попытка: заново создать шаблон Excel с нуля - в LibreOffice.

Теперь я думаю, что проблема полностью вводит в заблуждение. Если я использую только что созданный файл из LibreOffice, проверка вызывает исключение System.OutOfMemory из-за слишком большого количества ошибок проверки. Открытие в Excel требует ремонта, дает дополнительный лист и так далее.

Создание в LibreOffice, затем открыть в Excel, сохранение затем используя этот файл как шаблон производит гораздо лучший результат, хотя и не совершенен. Поскольку я копировал части из старого файла Excel в LO при создании нового файла, я предполагаю, что некоторые коррумпированные остатки были скопированы.

Я не могу поколебать ощущение, что это сам файл и не имеет никакого отношения к тому, как я его редактирую!

Завтра будет обновляться.

+3

Возможно, вы неправильно исправите проблему. Вместо того, чтобы ремонтировать файл, почему бы не исправлять часть openxml, которая создает это повреждение? Я предполагаю, что ваш 'XlHelper.ColorCellText()' создает неформатированный файл openxml. После применения вашей функции переименуйте ее ».zip "и откройте файл документа, чтобы увидеть результат своей модификации, и что вы должны добавить/удалить, чтобы исправить openxml. –

+0

@ MaximePorté. Там было сделано, что получил футболку. Откройте для предложений, но сомневайтесь, что есть много причудливых вещей, идущих на. – LocEngineer

+0

@ MaximePorté Chanched to EPPlus, не меняет штопанную вещь. Код отправлен – LocEngineer

ответ

0

OK. Расскажи это. Я создал совершенно новый файл с LibreOffice, убедившись, что вы ничего не копируете из исходного файла, и я бросил Interop в пользу ClosedXml.

=> Это произвело поврежденный файл, в котором мой первый лист был очищен, а его содержимое переместилось в «Restored_Table1».

После того, как я открыл новый новый шаблон с помощью Excel через Open/Repair и сохранил его, полученный, неокрашенный файл НЕ был поврежден.

=> Окраска производит «оригинальное» повреждение, все листы нетронутыми.

ClosedXml кажется немного медленнее Interop, но на данный момент мне все равно. Думаю, нам придется жить с «коррумпированным» сообщением и просто продолжать с ним.

Ненавижу XLSX.

Смежные вопросы