¿Cómo configurar el ancho de celda XLSX con EPPlus?

81

Hola, tengo este código donde creo un archivo xlsx y necesito preestablecer el ancho de las celdas de la hoja xlsx. El problema real es que cuando abro el excell necesito hacer doble clic en el espacio entre las columnas con el mouse para desenvolver las columnas y volver a ver los datos que están ocultos. ¿Hay alguna forma de hacer esto programáticamente con Epplus?

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
fuente

Respuestas:

151

Encuentro que configurar los anchos de columna después de haber completado todos los datos en la hoja funciona:

ws.Column(1).Width = 50;

También existe el método autoFitColumns, pero ignora las celdas con fórmulas y texto ajustado, por lo que no me funcionó.

ws.Cells["A1:K20"].AutoFitColumns();
aoifeL
fuente
10
Agregaría que si desea ajustar automáticamente todas las columnas en una hoja de trabajo, haga esto for (i = 1; i <= ws.Dimension.End.Column; i++) { ws.Column(i).AutoFit(); }
FarFigNewton
3
funciona, pero estableciendo un valor diferente, por ejemplo, quiero establecer el ancho de la columna en 7.86 pero se establece en 7.14 y para 3.5 se establece en 2.71
Mubashar
8
Una forma más sencilla de ajustar automáticamente todas las columnas es usar: ws.Cells [ws.Dimension.Address] .AutoFitColumns ()
Tevin
4
Estoy usando EPPlus 4.0.5 y esto funcionó para mí: ws.Cells.AutoFitColumns (); solo asegúrese de poner eso después de que se creen todas las celdas.
Baxter
1
@Jonah: Sí, vea la respuesta a continuación sobre cómo puede solucionarlo.
Mubashar
29

La respuesta real ya está marcada, esa es la forma correcta de configurar el ancho de la columna, pero hay un problema que es cuando el documento se abre por primera vez en Excel, recalcula el ancho de las columnas (no sé por qué), así que como mencioné en el comentario debajo de la respuesta marcada cuando Establecí el ancho de la columna en 7.86, lo restablece a 7.14 y 10.43 a 9.7x.

Encontré el siguiente código de este problema informado por epp para obtener el ancho de columna posible del armario según lo deseado.

//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
fuente
(1 + 2/3) == 1; (7/256) == 0; (
12/256
9

La respuesta de Mubashar Ahmad me ayudó, gracias por eso. Quería incluir cómo lo usé en mi proyecto. Lo convertí en un método de extensión y lo refactoricé.

Aquí está la implementación, que establece el ancho de celda para la primera columna de la hoja de trabajo.

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

Aquí está el método de extensión para establecer un ancho de columna más preciso en archivos EPPlus Excel, tenga en cuenta que este método debe estar dentro de una clase estática:

    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
fuente
Eso es intuitivo
Mubashar
2

Puede cambiar el ancho predeterminado de todas las columnas en la hoja de trabajo simplemente cambiando su propiedad DefaultColWidth :

worksheet.DefaultColWidth = 25;
Lorenzo Goldoni
fuente
0

Hay una manera más fácil. Excel cuantificará los anchos de columna pasados ​​para mostrar los doceavos por debajo de 1 y los séptimos por encima. Esto significa un resultado de escalera y no se pueden establecer muchos valores finales (por ejemplo, 3.5, 4.5, etc.).

Para compensar previamente un ancho, lo siguiente es suficiente.

SI DesiredWidth <1 entonces

AdjustedWidth = 12/7 * DesiredWidth

MÁS

Ancho ajustado = Ancho deseado + 5/7

TERMINARA SI

Escribir hoja de trabajo.Columna (i) .Ancho = Ancho ajustado con EPPLUS

Este es un ajuste monótono y Excel hace toda la cuantificación al abrir / guardar.

rivit
fuente