Как установить ширину ячейки XLSX с помощью EPPlus?

Здравствуйте, у меня есть этот код, в котором я создаю файл xlsx, и мне нужно предварительно установить ширину ячеек листа xlsx. Фактическая проблема заключается в том, что когда я открываю Excel, мне нужно дважды щелкнуть мышью по промежутку между столбцами, чтобы развернуть столбцы и восстановить скрытые данные. Есть ли способ сделать это программно с 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);

person themhz    schedule 01.02.2012    source источник


Ответы (5)


Я считаю, что установка ширины столбцов после того, как я заполнил все данные на листе, работает:

ws.Column(1).Width = 50;

Существует также метод autoFitColumns, но он игнорирует ячейки с формулами и обернутым текстом, поэтому у меня он не сработал.

ws.Cells["A1:K20"].AutoFitColumns();
person aoifeL    schedule 02.02.2012
comment
Я бы добавил, что если вы хотите автоматически подогнать все столбцы на листе, сделайте это for (i = 1; i <= ws.Dimension.End.Column; i++) { ws.Column(i).AutoFit(); } - person FarFigNewton; 22.05.2013
comment
он работает, но устанавливая другое значение, например, я хочу установить ширину столбца на 7,86, но он установлен на 7,14, а для 3,5 - на 2,71 - person Mubashar; 28.07.2013
comment
Более простой способ автоматически подогнать все столбцы - использовать: ws.Cells [ws.Dimension.Address] .AutoFitColumns () - person Tevin; 15.07.2014
comment
столбец Формат ширины пикселей? - person Магжан Куан; 09.06.2016
comment
Я использую EPPlus 4.0.5, и у меня это сработало: ws.Cells.AutoFitColumns (); только не забудьте поставить это после того, как все ячейки будут созданы. - person Baxter; 21.06.2016
comment
@MubasharAhmad Я второй - когда я пытаюсь установить его на 4, он устанавливает его на 3,29, что превращает 2016 в ###. Довольно раздражает. - person Jonah; 26.07.2016
comment
@Jonah: Да, пожалуйста, посмотрите ответ ниже, как вы можете это исправить. - person Mubashar; 27.07.2016
comment
Важное примечание: если вы используете очень большие данные для экспорта, явно задавайте ширину каждого столбца, например ws.Column (1) .Width = 50; намного быстрее, чем при использовании AutoFitColumns. Просто напоминание. - person curiousBoy; 11.04.2019
comment
Напоминаем, что функция AutoFitColumns () имеет серьезные проблемы с производительностью, особенно количество экспортируемых строк составляет около 500 КБ. - person curiousBoy; 16.04.2019

Фактический ответ уже отмечен, это правильный способ установки ширины столбца, но есть одна проблема: когда документ открывается в первый раз в Excel, он пересчитывает ширину столбцов (не знаю почему), поэтому, как я упоминал в комментарии под отмеченным ответом, когда Я установил ширину столбца на 7,86, она сбрасывает ее до 7,14 и 10,43 до 9,7x.

Я нашел следующий код из этой проблемы, о которой сообщил epp, чтобы получить желаемую ширину столбца в шкафу.

//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;
        }
person Mubashar    schedule 28.07.2013

Ответ Мубашара Ахмада помог мне, спасибо за это. Я хотел включить в свой проект, как я его использовал. Я превратил его в метод расширения и реорганизовал его.

Вот реализация, которая устанавливает ширину ячейки для первого столбца на листе.

    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;
    }
person Tyler Kalosza    schedule 09.05.2017
comment
Это интуитивно понятно - person Mubashar; 13.11.2019

Вы можете изменить ширину по умолчанию для всех столбцов на листе, просто изменив его свойство DefaultColWidth:

worksheet.DefaultColWidth = 25;
person Lorenzo Goldoni    schedule 21.01.2020

Есть способ попроще. Excel будет квантовать переданную ширину столбца, чтобы отобразить 12-ю меньше 1 и 7-ю вверху. Это означает, что результат лестничный, и многие конечные значения не могут быть получены (например, 3.5,4.5 и т. Д.).

Для предварительной компенсации ширины достаточно следующего.

ЕСЛИ DesiredWidth ‹1, тогда

AdjustWidth = 12/7 * DesiredWidth

ЕЩЕ

AdjustWidth = DesiredWidth + 5/7

ENDIF

Записать Worksheet.Column (i) .Width = AdjustedWidth с EPPLUS

Это монотонная настройка, и Excel выполняет все квантование при открытии / сохранении.

person rivit    schedule 30.10.2020