2012-02-01 4 views
50

Witaj Mam ten kod, w którym utworzę plik xlsx i muszę wstępnie ustawić szerokość komórek arkusza xlsx. Problem polega na tym, że po otwarciu excela muszę podwójnie kliknąć lukę między kolumnami za pomocą myszy, aby rozwinąć kolumny i zmienić ukryte dane. Czy istnieje sposób, aby to zrobić programowo z programem Epplus?Jak ustawić szerokość komórki xlsx za pomocą programu EPPlus w języku C#

using (ExcelPackage p = new ExcelPackage()) 
      { 
       String filepath = "C://StatsYellowPages.csv"; 
       DataSet ds = ExportCSVFileToDataset(filepath, "tblCustomers", "\t"); 
       //Here setting some document properties    
       p.Workbook.Properties.Title = "StatsYellowPages"; 

       //Create a sheet 
       p.Workbook.Worksheets.Add("Sample WorkSheet"); 
       ExcelWorksheet ws = p.Workbook.Worksheets[1]; 
       ws.Name = "StatsYellowPages"; //Setting Sheet's name 

       //Merging cells and create a center heading for out table 
       ws.Cells[1, 1].Value = "StatsYellowPages"; 
       ws.Cells[1, 1, 1, ds.Tables[0].Columns.Count].Merge = true; 
       ws.Cells[1, 1, 1, ds.Tables[0].Columns.Count].Style.Font.Bold = true; 
       ws.Cells[1, 1, 1, ds.Tables[0].Columns.Count].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center; 

       int colIndex = 1; 
       int rowIndex = 2; 

       foreach (DataColumn dc in ds.Tables[0].Columns) //Creating Headings 
       { 
        var cell = ws.Cells[rowIndex, colIndex]; 

        //Setting the background color of header cells to Gray 
        var fill = cell.Style.Fill; 
        fill.PatternType = ExcelFillStyle.Solid; 
        fill.BackgroundColor.SetColor(Color.Gray); 


        //Setting Top/left,right/bottom borders. 
        var border = cell.Style.Border; 
        border.Bottom.Style = ExcelBorderStyle.Thin; 
        border.Top.Style = ExcelBorderStyle.Thin; 
        border.Left.Style = ExcelBorderStyle.Thin; 
        border.Right.Style = ExcelBorderStyle.Thin; 

        //Setting Heading Value in cell 
        cell.Value = dc.ColumnName; 

        colIndex++; 
       } 

       foreach (DataRow dr in ds.Tables[0].Rows) // Adding Data into rows 
       { 
        colIndex = 1; 
        rowIndex++; 
        foreach (DataColumn dc in ds.Tables[0].Columns) 
        { 
         var cell = ws.Cells[rowIndex, colIndex]; 
         //Setting Value in cell 
         cell.Value = dr[dc.ColumnName].ToString(); 
         //Setting borders of cell 
         var border = cell.Style.Border;      
         colIndex++; 
        } 
       } 


       //Generate A File with Random name 
       Byte[] bin = p.GetAsByteArray(); 
       string file = "c:\\StatsYellowPages.xlsx"; 
       File.WriteAllBytes(file, bin); 

Odpowiedz

98

Uważam, że ustawienie szerokości kolumn po I wypełnieniu wszystkich danych na arkuszu działa:

ws.Column(1).Width = 50; 

Istnieje również metoda autoFitColumns ale ignoruje komórki z formułami i zawinięty tekst tak to nie działa dla mnie.

ws.Cells["A1:K20"].AutoFitColumns(); 
+1

thanx wydaje ver dobrze pracować . – themis

+6

Chciałbym dodać, że jeśli chcesz autofit wszystkie kolumny w arkuszu należy to zrobić 'for (i = 1; i <= ws.Dimension.End.Column; i ++) { \t ws.Column (i) .AutoFit (); } ' – guanome

+2

działa, ale ustawia inną wartość, na przykład chcę ustawić szerokość kolumny na 7,86, ale ustawia się na 7,14, a na 3.5 to ustawienie na 2.71 –

18

Rzeczywista Odpowiedź została już oznaczona ów właściwy sposób ustawiania szerokości kolumny, ale jest jeden problem, który jest, gdy dokument jest otwierany po raz pierwszy w programie Excel, to przelicza szerokość kolumny (nie wiem dlaczego), więc jak już wspomniałem w komentarzu poniżej zaznaczonej odpowiedzi, gdy ustawię szerokość kolumny na 7,86, resetuje ją do 7,14 i 10,43 do 9,7x.

Znalazłem następujący kod z this epp reported issue, aby uzyskać możliwą szerokość kolumny w zależności od potrzeb.

//get 7.14 in excel 
ws.Column(1).Width = 7.86; 

//get 7.86 in excel 
ws.Column(1).Width = GetTrueColumnWidth(7.86); 

public static double GetTrueColumnWidth(double width) 
     { 
      //DEDUCE WHAT THE COLUMN WIDTH WOULD REALLY GET SET TO 
      double z = 1d; 
      if (width >= (1 + 2/3)) 
      { 
       z = Math.Round((Math.Round(7 * (width - 1/256), 0) - 5)/7, 2); 
      } 
      else 
      { 
       z = Math.Round((Math.Round(12 * (width - 1/256), 0) - Math.Round(5 * width, 0))/12, 2); 
      } 

      //HOW FAR OFF? (WILL BE LESS THAN 1) 
      double errorAmt = width - z; 

      //CALCULATE WHAT AMOUNT TO TACK ONTO THE ORIGINAL AMOUNT TO RESULT IN THE CLOSEST POSSIBLE SETTING 
      double adj = 0d; 
      if (width >= (1 + 2/3)) 
      { 
       adj = (Math.Round(7 * errorAmt - 7/256, 0))/7; 
      } 
      else 
      { 
       adj = ((Math.Round(12 * errorAmt - 12/256, 0))/12) + (2/12); 
      } 

      //RETURN A SCALED-VALUE THAT SHOULD RESULT IN THE NEAREST POSSIBLE VALUE TO THE TRUE DESIRED SETTING 
      if (z > 0) 
      { 
       return width + adj; 
      } 

      return 0d; 
     } 
2

Odpowiedź Mubashara Ahmada pomógł mi, dziękuję za to. Chciałem uwzględnić, w jaki sposób wykorzystałem go w moim projekcie. Zrobiłem to metodą rozszerzającą i refaktoryzowałem.

Oto implementacja, która określa szerokość komórki dla pierwszej kolumny w arkuszu.

worksheet.Column(1).SetTrueColumnWidth(28); 

Oto metoda rozszerzenie do ustawiania dokładniejsze szerokość kolumny w plikach EPPlus Excel należy pamiętać, że ta metoda musi być wewnątrz klasy statycznej:

public static void SetTrueColumnWidth(this ExcelColumn column, double width) 
    { 
     // Deduce what the column width would really get set to. 
     var z = width >= (1 + 2/3) 
      ? Math.Round((Math.Round(7 * (width - 1/256), 0) - 5)/7, 2) 
      : Math.Round((Math.Round(12 * (width - 1/256), 0) - Math.Round(5 * width, 0))/12, 2); 

     // How far off? (will be less than 1) 
     var errorAmt = width - z; 

     // Calculate what amount to tack onto the original amount to result in the closest possible setting. 
     var adj = width >= 1 + 2/3 
      ? Math.Round(7 * errorAmt - 7/256, 0)/7 
      : Math.Round(12 * errorAmt - 12/256, 0)/12 + (2/12); 

     // Set width to a scaled-value that should result in the nearest possible value to the true desired setting. 
     if (z > 0) 
     { 
      column.Width = width + adj; 
      return; 
     } 

     column.Width = 0d; 
    }