2015-07-21 29 views
6

tworzę arkusz z punktu A List<object[]> korzystając LoadFromArraysKorzystanie EPPlus jak mogę wygenerować arkusz kalkulacyjny, gdzie liczby są liczbami nie tekst

Pierwszy wpis w tablicy jest tytuł, pozostałe wpisy są ewentualnie numery, tekstu lub daty (ale takie same dla każdej tablicy na liście).

Wygenerowany arkusz programu Excel ma zielony trójkąt z ostrzeżeniem, że liczby są sformatowane jako tekst.

I pętli wszystkich komórek i ustawić ich format na numer jak tak ws.Cells[i, j].Style.Numberformat.Format = "0";

jednak pozostaje problem i wciąż widzę zieloną ostrzeżenie, chociaż format numeru jest ustawiona na liczbę kiedy patrzę w Format Cell... dialog.

Jakie są moje opcje? Możliwe jest, że wiem trochę więcej o tym, jaki typ jest w każdej kolumnie, ale jak mam ustawić tytuł kolumny?

Czy istnieje lepsze rozwiązanie niż EPPlus? lub trochę więcej post-przetwarzania arkusza kalkulacyjnego, który mogę zrobić przed pobraniem?

+1

Zazwyczaj te zielone trójkąty pochodzą z liczb (w kodzie) przechowywanych w zmiennych łańcuchowych lub właściwościach. Więc niezależnie od tego, jak ustawić Excela, musiałbyś przekonwertować ciąg na liczbę w kodzie. Czy to możliwe? – Ernie

Odpowiedz

8

Ponieważ używasz obiektom tablice mogą zawierać liczb i łańcuchów, które wyglądają jak liczb trzeba będzie przejść przez każdego obiektu i określić jego typ:

[TestMethod] 
public void Object_Type_Write_Test() 
{ 
    //http://stackoverflow.com/questions/31537981/using-epplus-how-can-i-generate-a-spreadsheet-where-numbers-are-numbers-not-text 
    var existingFile = new FileInfo(@"c:\temp\temp.xlsx"); 
    if (existingFile.Exists) 
     existingFile.Delete(); 

    //Some data 
    var list = new List<Object[]> 
    { 
     new object[] 
     { 
      "111.11", 
      111.11, 
      DateTime.Now 
     } 
    }; 

    using (var package = new ExcelPackage(existingFile)) 
    { 
     var ws = package.Workbook.Worksheets.Add("Sheet1"); 
     ws.Cells[1, 1, 2, 2].Style.Numberformat.Format = "0"; 
     ws.Cells[1, 3, 2, 3].Style.Numberformat.Format = "[$-F400]h:mm:ss\\ AM/PM"; 

     //This will cause numbers in string to be stored as string in excel regardless of cell format 
     ws.Cells["A1"].LoadFromArrays(list); 

     //Have to go through the objects to deal with numbers as strings 
     for (var i = 0; i < list.Count; i++) 
     { 
      for (var j = 0; j < list[i].Count(); j++) 
      { 

       if (list[i][j] is string) 
        ws.Cells[i + 2, j + 1].Value = Double.Parse((string) list[i][j]); 
       else if (list[i][j] is double) 
        ws.Cells[i + 2, j + 1].Value = (double)list[i][j]; 
       else 
        ws.Cells[i + 2, j + 1].Value = list[i][j]; 

      } 
     } 

     package.Save(); 
    } 
} 

Z powyższego widać na obrazek poniżej jako wyjście Uwaga lewy górny róg komórki z zieloną strzałką, ponieważ był to ciąg znaków, który został napisany przez LoadFromArray który wygląda jak numer:

Excel Output

+0

Losowanie i mały haczyk to niewielkie wynagrodzenie za tę fantastyczną pomoc ... Naprawdę miotałem to! – Loofer

+0

@Loofer Na, bez problemu. Cieszę się, że to pomogło. – Ernie

1

I stworzył met przedłużacza od LoadFormulasFromArray, na podstawie EPPlus LoadFromArray. Metoda zakłada, że ​​wszystkie obiekty na liście mają być traktowane jako formuły (w przeciwieństwie do LoadFromArray). Ogromny obraz jest taki, że zarówno właściwości określonego typu, jak i właściwości są pobierane. Widzę to jako błąd, ponieważ nie ma sposobu na rozróżnienie, czy ciąg znaków jest Text lub Formula. Wdrożenie typu Formula umożliwiłoby przeładowanie i sprawdzenie typu, umożliwiając zawsze robienie właściwych rzeczy.

// usage: ws.Cells[2,2].LoadFormulasFromArrays(MyListOfObjectArrays) 

public static class EppPlusExtensions 
{ 
    public static ExcelRangeBase LoadFormulasFromArrays(this ExcelRange Cells, IEnumerable<object[]> Data) 
    { 
     //thanx to Abdullin for the code contribution 
     ExcelWorksheet _worksheet = Cells.Worksheet; 
     int _fromRow = Cells.Start.Row; 
     int _fromCol = Cells.Start.Column; 
     if (Data == null) throw new ArgumentNullException("data"); 

     int column = _fromCol, row = _fromRow; 

     foreach (var rowData in Data) 
     { 
      column = _fromCol; 
      foreach (var cellData in rowData) 
      { 
       Cells[row, column].Formula = cellData.ToString(); 
       column += 1; 
      } 
      row += 1; 
     } 
     return Cells[_fromRow, _fromCol, row - 1, column - 1]; 
    } 
}