Quantcast
Channel: Open XML Format SDK forum
Viewing all articles
Browse latest Browse all 1288

Solution: How to AutoFit Excel Content

$
0
0

I, like most, am new to Open XML.  I was trying to find a way to size the column to my largest item.  I mostly found that the current spec doesn't support it automatically.  After poking around I found a formula which I rework to calculate the width based on the pixel width of the string.  I then found a way to size the column.

Here is the complete source code to do it.  I should mention that I am NOT searching for the largest string in the column but rather calculating 1 item.  Haven't quite figured out how to do search yet.

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;

namespace AutoFit
{
  class Program
  {
   static void Main(string[] args)
   {
     string docName = @"D:\Temp\MyFirstExcel.xlsx";

     // Create a Wordprocessing document.
     using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(docName, SpreadsheetDocumentType.Workbook))
     {
      // Add a WorkbookPart to the document.
      WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart();
      workbookpart.Workbook = new Workbook();

      // Add a WorksheetPart to the WorkbookPart.
      WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
      worksheetPart.Worksheet = new Worksheet();

      // ####################################
      //   IMPORTANT STUFF
      // ####################################

      string strText = "This is some really, really long text to display.";
      double width = GetWidth("Calibri", 11, strText);

      string strText2 = "123";
      double width2 = GetWidth("Calibri", 11, strText2);

      Columns columns = new Columns();
      columns.Append(CreateColumnData(2, 2, width));
      columns.Append(CreateColumnData(3, 3, width2));
      worksheetPart.Worksheet.Append(columns);

      // ####################################
      //   END OF IMPORTANT STUFF
      // ####################################

      SheetData sd = new SheetData();
      worksheetPart.Worksheet.Append(sd);

      // Add Sheets to the Workbook.
      Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());


      // Append a new worksheet and associate it with the workbook.
      Sheet sheet = new Sheet()
      {
        Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart),
        SheetId = 1,
        Name = "mySheet"
      };
      sheets.Append(sheet);



      // Add Data
      Row row = new Row();

      Cell cell;

      // String
      cell = CreateSpreadsheetCellIfNotExist(worksheetPart.Worksheet, "B2");
      cell.CellValue = new CellValue(strText);
      cell.DataType = CellValues.String;


      // Number
      int count = 123;
      cell = CreateSpreadsheetCellIfNotExist(worksheetPart.Worksheet, "C2");
      CellValue cellValue = new CellValue(count.ToString());
      cell.CellValue = cellValue;
      cell.DataType = CellValues.Number;

      workbookpart.Workbook.Save();

      // Close the document.
      spreadsheetDocument.Close();
     }
   }

   private static double GetWidth(string font, int fontSize, string text)
   {
     System.Drawing.Font stringFont = new System.Drawing.Font(font, fontSize);
     return GetWidth(stringFont, text);
   }

   private static double GetWidth(System.Drawing.Font stringFont, string text)
   {
     // This formula is based on this article plus a nudge ( + 0.2M )
     // http://msdn.microsoft.com/en-us/library/documentformat.openxml.spreadsheet.column.width.aspx
     // Truncate(((256 * Solve_For_This + Truncate(128 / 7)) / 256) * 7) = DeterminePixelsOfString

     Size textSize = TextRenderer.MeasureText(text, stringFont);
     double width = (double)(((textSize.Width / (double)7) * 256) - (128 / 7)) / 256;
     width = (double)decimal.Round((decimal)width + 0.2M, 2);

     return width;
   }

   private static Column CreateColumnData(UInt32 StartColumnIndex, UInt32 EndColumnIndex, double ColumnWidth)
   {
     Column column;
     column = new Column();
     column.Min = StartColumnIndex;
     column.Max = EndColumnIndex;
     column.Width = ColumnWidth;
     column.CustomWidth = true;
     return column;
   }

   // Given a Worksheet and a cell name, verifies that the specified cell exists.
   // If it does not exist, creates a new cell.
   private static Cell CreateSpreadsheetCellIfNotExist(Worksheet worksheet, string cellName)
   {
     string columnName = GetColumnName(cellName);
     uint rowIndex = GetRowIndex(cellName);

     IEnumerable<Row> rows = worksheet.Descendants<Row>().Where(r => r.RowIndex.Value == rowIndex);
     Cell cell;

     // If the Worksheet does not contain the specified row, create the specified row.
     // Create the specified cell in that row, and insert the row into the Worksheet.
     if (rows.Count() == 0)
     {
      Row row = new Row() { RowIndex = new UInt32Value(rowIndex) };
      cell = new Cell() { CellReference = new StringValue(cellName) };
      row.Append(cell);
      worksheet.Descendants<SheetData>().First().Append(row);
      worksheet.Save();
     }
     else
     {
      Row row = rows.First();

      IEnumerable<Cell> cells = row.Elements<Cell>().Where(c => c.CellReference.Value == cellName);

      // If the row does not contain the specified cell, create the specified cell.
      if (cells.Count() == 0)
      {
        cell = new Cell() { CellReference = new StringValue(cellName) };
        row.Append(cell);
        worksheet.Save();
      }
      else
        cell = cells.First();
     }

     return cell;
   }

   // Given a cell name, parses the specified cell to get the column name.
   private static string GetColumnName(string cellName)
   {
     // Create a regular expression to match the column name portion of the cell name.
     Regex regex = new Regex("[A-Za-z]+");
     Match match = regex.Match(cellName);

     return match.Value;
   }

   // Given a cell name, parses the specified cell to get the row index.
   private static uint GetRowIndex(string cellName)
   {
     // Create a regular expression to match the row index portion the cell name.
     Regex regex = new Regex(@"\d+");
     Match match = regex.Match(cellName);

     return uint.Parse(match.Value);
   }
  }
}

Viewing all articles
Browse latest Browse all 1288

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>