G+

Open XML Cannot open the Excel 2010

Программирование Asp.net
Предыдущий Следующий

 Для работы с Excel мы используем OpenXML и в частности библиотеку SpreadsheetLight. Но появилась проблема с Excel 2010 в стилях. Суть какая: если вы для формирования Excel файла используете шаблон, и в нем применяете какие-то стили (цвет ячеек или текста), то OpenXML при работе с таким файлом добавит в конце файла xl/styles.xml код:

<x:extLst>
 <x:ext
          xmlns:x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"                          
          uri="{EB79DEF2-80B8-43e5-95BD-54CBDDF9020C}">
                 <x14:slicerStyles defaultSlicerStyle="SlicerStyleLight1"/>
   </x:ext>
   <x:ext xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main"
             uri="{9260A510-F301-46a8-8635-F512D64BE5F5}">
                           <x15:timelineStyles defaultTimelineStyle="TimeSlicerStyleLight1"/>
   </x:ext>
</x:extLst>

После того как вы сохраните файл и откроете его снова в Excel , этот код превратится в такой вид: 

<extLst>
<ext uri="{EB79DEF2-80B8-43e5-95BD-54CBDDF9020C}" 
xmlns:x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main">
   <x14:slicerStyles defaultSlicerStyle="SlicerStyleLight1"/>
</ext>

<x:ext uri="{9260A510-F301-46a8-8635-F512D64BE5F5}"
xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main">
  <x15:timelineStyles defaultTimelineStyle="TimeSlicerStyleLight1"/>
</x:ext>
</extLst>

 

И вы получите ошибку, когда откроете такой файл и у вас пропадут все стили. На данный момент, какого-то красивого решение этой проблемы нет. Единственное что можно придумать это открыть Excel как zip-файл (а он по сути таким и является) и удалить из него не нужный кусок xml.

Итак, для открытия файла я использую DotNetZip. Вот пример метода, в который я передаю путь к Excel файлу. Этот метод нужно вызывать после того, как вы закончили работу с OpenXML:

public static class OpenXmlExcelHelper
 {
  public static void FixedBugExcel2010(string path)
   {
      using (var zf = Ionic.Zip.ZipFile.Read(path))
      {
         var ze = zf["xl/styles.xml"];
         using (var ms = new System.IO.MemoryStream())
         {
             ze.Extract(ms);
             ms.Position = 0;
             var sr = new System.IO.StreamReader(ms);
             string streamdata = sr.ReadToEnd();
              var startIndex = streamdata.IndexOf("<x:extLst>");
              if (startIndex != -1)
              {
                 streamdata = streamdata
                  .Remove(startIndex, streamdata.IndexOf("</x:extLst>") - startIndex + 11);
              }
             sr.Close();
             zf.UpdateEntry("xl/styles.xml", streamdata, System.Text.Encoding.UTF8);
             zf.Save();
          }  } } }

Работа с Excel выглядит примерно так:

using (SLDocument sl = new SLDocument(pathFile, "Sheet1"))
{
       //Что-то делаем
       sl.Save();
}
OpenXmlExcelHelper.FixedBugExcel2010(pathFile);

Комментарий:
  • В 23.01.2014 15:18:18, Аноним

    Спасибо. ХОрошее решение. Недавно была такая же беда. Пришлось воспользоваться ClosedXML , но у нее беда при больших обьемах, когда все записи не влазять за раз в ОЗУ, тогда дела не будет. Поэтому работать прийдется только с OpenXML. Еще раз спасибо. Петя.

Самостоятельный отпуск Опыт заказа вывоза мусора в Киеве