2012-02-01 110 views
50

你好我有這個代碼,我創建一個xlsx文件,我需要預先設置xlsx表格單元格的寬度。 實際的問題是,當我打開excell我需要用鼠標雙擊列之間的差距,以解開列和revieal隱藏的數據。 有沒有辦法用Epplus來做這個程序?如何在C#中使用EPPlus設置xlsx單元格寬度

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); 

回答

98

我發現,設置列寬我已經填寫在表中的所有數據後,工作原理:

ws.Column(1).Width = 50; 

也有autoFitColumns方法,但是這忽略細胞公式和換行文本等等它不適合我。

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

感謝名單,似乎工作版本好。 – themis 2012-02-02 16:33:01

+6

我會補充說,如果你想自動調整工作表中的所有列,請執行以下操作:for(i = 1; i <= ws.Dimension.End.Column; i ++){ws.Column(i).AutoFit ); }' – guanome 2013-05-22 13:25:33

+2

它的工作原理,但設置不同的值,例如我想設置列的寬度爲7.86,但它設置爲7.14和3.5設置爲2.71 – 2013-07-28 08:15:27

18

實際的答案已經標明這就是設置列寬以正確的方式,但有一個問題,當文件打開時第一次在Excel中,它會重新計算列的寬度(不知道爲什麼),所以正如我所說在下面的評論中,當我將列寬設置爲7.86時,將其重置爲7.14和10.43至9.7x。

我發現下面的代碼從this epp reported issue得到最接近可能的列寬根據需要。

//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

穆巴沙爾艾哈邁德的回答幫了我,謝謝你。我想包括我在項目中如何使用它。我已經將它變成了一個擴展方法並對其進行了重構。

這是實現,它爲工作表中的第一列設置單元格寬度。

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

下面是設置在EPPlus Excel文件更準確的列寬擴展方法,注意,這個方法必須是靜態類的內部:

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; 
    } 
相關問題