Wie stelle ich die XLSX-Zellenbreite mit EPPlus ein?

81

Hallo, ich habe diesen Code, in dem ich eine XLSX-Datei erstelle und die Breite der XLSX-Blattzellen voreinstellen muss. Das eigentliche Problem ist, dass ich beim Öffnen des Excells mit der Maus auf die Lücke zwischen den Spalten doppelklicken muss, um die Spalten zu entpacken und die verborgenen Daten wiederzugeben. Gibt es eine Möglichkeit, dies programmatisch mit Epplus durchzuführen?

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

Antworten:

151

Ich finde, dass das Einstellen der Spaltenbreiten, nachdem ich alle Daten auf dem Blatt ausgefüllt habe, funktioniert:

ws.Column(1).Width = 50;

Es gibt auch die autoFitColumns-Methode, die jedoch Zellen mit Formeln und umbrochenem Text ignoriert, sodass sie bei mir nicht funktioniert hat.

ws.Cells["A1:K20"].AutoFitColumns();
aoifeL
quelle
10
Ich würde hinzufügen, dass, wenn Sie alle Spalten in einem Arbeitsblatt for (i = 1; i <= ws.Dimension.End.Column; i++) { ws.Column(i).AutoFit(); }
automatisch
3
es funktioniert, aber einen anderen Wert einstellen, zum Beispiel möchte ich die Breite der Spalte auf 7,86 einstellen, aber es wird auf 7,14 eingestellt und für 3,5 wird es auf 2,71 eingestellt
Mubashar
8
Eine einfachere Möglichkeit, alle Spalten automatisch anzupassen, ist die Verwendung von: ws.Cells [ws.Dimension.Address] .AutoFitColumns ()
Tevin
4
Ich verwende EPPlus 4.0.5 und dies hat bei mir funktioniert: ws.Cells.AutoFitColumns (); Stellen Sie dies einfach sicher, nachdem alle Zellen erstellt wurden.
Baxter
1
@ Jonah: Ja, bitte sehen Sie die folgende Antwort, wie Sie es beheben können.
Mubashar
29

Die tatsächliche Antwort ist bereits markiert. Dies ist die richtige Methode zum Festlegen der Spaltenbreite. Es gibt jedoch ein Problem: Wenn das Dokument zum ersten Mal in Excel geöffnet wird, wird die Spaltenbreite neu berechnet (ich weiß nicht warum), wie im Kommentar unter der markierten Antwort erwähnt Ich setze die Spaltenbreite auf 7,86 und setze sie auf 7,14 und 10,43 auf 9,7x zurück.

Ich fand folgenden Code aus diesem von epp gemeldeten Problem , um die mögliche Spaltenbreite des Schranks wie gewünscht zu erhalten.

//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;
        }
Mubashar
quelle
(1/3/3) == 1; (7/256) == 0; (
12/256
9

Mubashar Ahmads Antwort hat mir geholfen, danke dafür. Ich wollte in mein Projekt aufnehmen, wie ich es verwendet habe. Ich habe es zu einer Erweiterungsmethode gemacht und es überarbeitet.

Hier ist die Implementierung, die die Zellenbreite für die erste Spalte im Arbeitsblatt festlegt.

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

Hier ist die Erweiterungsmethode zum Festlegen einer genaueren Spaltenbreite in EPPlus Excel-Dateien. Beachten Sie, dass sich diese Methode innerhalb einer statischen Klasse befinden muss:

    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;
    }
Tyler Kalosza
quelle
Das ist intuitiv
Mubashar
2

Sie können die Standardbreite aller Spalten im Arbeitsblatt ändern, indem Sie einfach die DefaultColWidth- Eigenschaft ändern :

worksheet.DefaultColWidth = 25;
Lorenzo Goldoni
quelle
0

Es gibt einen einfacheren Weg. Excel quantisiert die übergebenen Spaltenbreiten, um Zwölftel unter 1 und Siebzehntel darüber anzuzeigen. Dies bedeutet ein Treppenergebnis und viele Endwerte können nicht erreicht werden (z. B. 3,5,4,5 usw.).

Um eine Breite vorkompensieren zu können, ist Folgendes ausreichend.

WENN DesiredWidth <1 dann

AdjustedWidth = 12/7 * DesiredWidth

SONST

AdjustedWidth = DesiredWidth + 5/7

ENDIF

Schreiben Sie Worksheet.Column (i) .Width = AdjustedWidth mit EPPLUS

Dies ist eine monotone Anpassung, und Excel führt die gesamte Quantisierung beim Öffnen / Speichern durch.

rivit
quelle