2015-03-13 11 views
0

Я не могу использовать NPOI для сохранения изменений на xlsx на диске при попытке сделать это из библиотеки DLL.Запись файла с использованием NPOI

У меня есть набор данных, которые я сейчас храню в базе данных, и для него ORM для взрослых. Домашний ORM размещается в собственной DLL. Я хочу написать утилиту, которая использует ORM, чтобы взять подмножество данных для чтения/записи. Я использую NPOI (v2.1.3.0) для этого.

Утилита вызовов выглядит следующим образом:

private void Test_Click(object sender, RoutedEventArgs e) 
    { 
     var model = new ExcelDal(this.filename); 
     model.Clients.Save(new Client { 
       DateOfBirth = DateTime.Now, DisplayName = "Test", Male = true 
     }); 
    } 

И я бы ожидать, что я бы получить XLSX листом под названием «Клиент» и колонки текста для «DateOfBirth», «DisplayName» и «Мужской ». Файл действительно создан, но попытка его открыть не выполняется. С другой стороны, если я заменю этот код с этим, я получаю именно то, что ожидал:

private void Test_Click(object sender, RoutedEventArgs e) 
    { 
     IWorkbook workbook = new XSSFWorkbook(); 
     ISheet sheet = workbook.CreateSheet("Client"); 
     MainWindow.Create(sheet, 0, "DateOfBirth", "DisplayName", "Male"); 
     MainWindow.Create(sheet, 1, "1900/1/1", "Test", "true"); 

     FileMode mode = File.Exists(this.filename) ? FileMode.Truncate : FileMode.Create; 

     using (FileStream fs = new FileStream(this.filename, mode, FileAccess.ReadWrite)) 
     { 
      workbook.Write(fs); 
     } 
    } 

    private static void Create(ISheet sheet, int rowNum, params string[] values) 
    { 
     IRow row = sheet.CreateRow(rowNum); 
     for (int i = 0; i < values.Length; i++) 
     { 
      ICell cell = row.CreateCell(i); 
      cell.SetCellValue(values[i]); 
     } 
    } 

Действия по устранению неполадок пытался до сих пор:

  • Переименованный созданный файл на молнии и экстрагируют его, его является допустимым zip.
  • Застегнул файл и переименовал его в xlsx, я получил немного другую ошибку, но все равно не открывается.
  • Все есть .Net 4.5
  • Другой SO question, упомянутый с помощью ICreationHelper, в ответ на преобразование значений строк, поэтому я тоже пробовал это, но ничего не изменил.
  • Несколько заметок на ORM, поскольку включение всего соответствующего кода может быть излишним. Я использую почти тот же код, что и произведение выше, которое работает; Я построил тестовый код, чтобы попытаться выяснить, что я делаю неправильно, но он просто сработал.

Это то, что код, чтобы установить значение ячейки выглядит (обратите внимание, что значения уже ToString() 'd к тому времени, которое они получают на самом деле быть сохранены):

public void SetValue(IRow row, string column, string value) 
    { 
     int columnIndex = this.GetColumnIndex(column); 
     ICell cell = ColumnMapping.GetOrCreateCell(row, columnIndex); 
     cell.SetCellValue(value); 
    } 

    private static ICell GetOrCreateCell(IRow row, int columnIndex) 
    { 
     return row.GetCell(columnIndex) ?? row.CreateCell(columnIndex); 
    } 

Это что код для сохранения файла выглядит так:

public void Save() 
    { 
     FileMode mode = File.Exists(this.filename) ? FileMode.Truncate : FileMode.Create; 

     using (FileStream fs = new FileStream(this.filename, mode, FileAccess.ReadWrite)) 
     { 
      this.workbook.Write(fs); 
     } 
    } 

Невозможно обнаружить различия. Единственное, что может быть, это то, что вы используете NPOI косвенно, через вышеупомянутую ORM, и один использует ее напрямую.

ответ

0

Мне не удалось найти способ сделать это надежно с помощью NPOI. Файлы, созданные утилитой, всегда выходили из строя. Я перешел на EPPlus для xlsx. Результирующий код выглядит следующим образом:

public void SetValue(int row, string column, string value) 
{ 
    row += 2; //EPPlus is 1-index based, and the first row is the heading 
    int columnIndex = this.GetColumnIndex(column); 
    this.excelSheet.SetValue(row, columnIndex, value); 
} 

соответствующий код для сохранения файла выглядит следующим образом:

public void Dispose() 
{ 
    //ExcelPackage is gone once it is written out. It must be re-created. 
    this.excelPackage.SaveAs(new FileInfo(this.filename)); 
    this.excelPackage.Dispose(); 
} 

Таким образом, реализация добавить Flush(), который будет распоряжаться текущей ExcelPackage , затем весь файл ExcelSheet в настоящее время в памяти, а затем повторно инициализируйте все из выписанного файла.

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