2013-08-16 87 views
10

OpenXMLを使用してExcelファイルを生成するコードを作成しました。 以下は、Excelで列を生成するコードです。OpenXML:Excelでの自動サイズの列幅

Worksheet worksheet = new Worksheet(); 
      Columns columns = new Columns(); 
      int numCols = dt1.Columns.Count; 
      for (int col = 0; col < numCols; col++) 
      { 
        Column c = CreateColumnData((UInt32)col + 1, (UInt32)numCols + 1, 20.42578125D); 

       columns.Append(c); 
      } 
      worksheet.Append(columns); 

また、以下の行を作成して列を作成しました。

Column c = new Column() { Min = (UInt32Value)1U, Max = (UInt32Value)1U, Width = 25.42578125D, BestFit = true, CustomWidth = true}; 

私はBestFitを使用するとうまくいくと思いました。しかし、それは自動サイズを設定しません。

私にこれを手伝ってください。

ありがとう、

答えて

7

BestFitプロパティは、(Excelによる最適化のための)情報プロパティです。それでも列の幅を指定する必要があります。つまり、セルの内容に応じて列の幅を実際に計算する必要があります。 Open XML SDKではこれが自動的に行われないため、サードパーティライブラリを使用する方がよいでしょう。ここ

+1

このBestFitプロパティのよりよい解決策であるべきですか?現在は、2014年8月です。 –

0

可能式 幅=切り捨て([{文字数} * {最大桁幅} + {5画素パディング}]/{最大桁幅} * 256)/ 256

10

自分が持っています残念ながらそれを計算してください

これは私が持っているものです。これは私が設定したいくつかのスタイルを処理するためにいくつかの余分なコードを含む表形式のデータに有効です。それは決して完璧ではありませんが、私が必要とするもののために働きます。

private WorksheetPart mySheetPart; 
private void WriteToTable() 
{ 
     //Get your sheet data - write Rows and Cells 
     SheetData sheetData = GetSheetData(); 

     //get your columns (where your width is set) 
     Columns columns = AutoSize(sheetData); 

     //add to a WorksheetPart.WorkSheet 
     mySheetPart.Worksheet = new Worksheet(); 
     mySheetPart.Worksheet.Append(columns); 
     mySheetPart.Worksheet.Append(sheetData); 
} 

private Columns AutoSize(SheetData sheetData) 
{ 
     var maxColWidth = GetMaxCharacterWidth(sheetData); 

     Columns columns = new Columns(); 
     //this is the width of my font - yours may be different 
     double maxWidth = 7; 
     foreach (var item in maxColWidth) 
     { 
      //width = Truncate([{Number of Characters} * {Maximum Digit Width} + {5 pixel padding}]/{Maximum Digit Width}*256)/256 
      double width = Math.Truncate((item.Value * maxWidth + 5)/maxWidth * 256)/256; 

      //pixels=Truncate(((256 * {width} + Truncate(128/{Maximum Digit Width}))/256)*{Maximum Digit Width}) 
      double pixels = Math.Truncate(((256 * width + Math.Truncate(128/maxWidth))/256) * maxWidth); 

      //character width=Truncate(({pixels}-5)/{Maximum Digit Width} * 100+0.5)/100 
      double charWidth = Math.Truncate((pixels - 5)/maxWidth * 100 + 0.5)/100; 

      Column col = new Column() { BestFit = true, Min = (UInt32)(item.Key + 1), Max = (UInt32)(item.Key + 1), CustomWidth = true, Width = (DoubleValue)width }; 
      columns.Append(col); 
     } 

     return columns; 
    } 


    private Dictionary<int, int> GetMaxCharacterWidth(SheetData sheetData) 
    { 
     //iterate over all cells getting a max char value for each column 
     Dictionary<int, int> maxColWidth = new Dictionary<int, int>(); 
     var rows = sheetData.Elements<Row>(); 
     UInt32[] numberStyles = new UInt32[] { 5, 6, 7, 8 }; //styles that will add extra chars 
     UInt32[] boldStyles = new UInt32[] { 1, 2, 3, 4, 6, 7, 8 }; //styles that will bold 
     foreach (var r in rows) 
     { 
      var cells = r.Elements<Cell>().ToArray(); 

      //using cell index as my column 
      for (int i = 0; i < cells.Length; i++) 
      { 
       var cell = cells[i]; 
       var cellValue = cell.CellValue == null ? string.Empty : cell.CellValue.InnerText; 
       var cellTextLength = cellValue.Length; 

       if (cell.StyleIndex != null && numberStyles.Contains(cell.StyleIndex)) 
       { 
        int thousandCount = (int)Math.Truncate((double)cellTextLength/4); 

        //add 3 for '.00' 
        cellTextLength += (3 + thousandCount); 
       } 

       if (cell.StyleIndex != null && boldStyles.Contains(cell.StyleIndex)) 
       { 
        //add an extra char for bold - not 100% acurate but good enough for what i need. 
        cellTextLength += 1; 
       } 

       if (maxColWidth.ContainsKey(i)) 
       { 
        var current = maxColWidth[i]; 
        if (cellTextLength > current) 
        { 
         maxColWidth[i] = cellTextLength; 
        } 
       } 
       else 
       { 
        maxColWidth.Add(i, cellTextLength); 
       } 
      } 
     } 

     return maxColWidth; 
    } 
+0

"GetSheetData()"メソッドを定義していません。 –

+0

あなたが何を意味するのか分かりますが、あなたはすべてのセルの値を設定する独自の実装を書いてから、列の幅を設定することを続けます。 –

+2

AutoSize()のcharWidth変数は使用されていませんか? – Macke

1

私はそれに見て時間がなかったが、代わりに単にコメントやa linkを残して、私は私が一見これに関するいくつかの研究を行っている誰かからのコメントを共有しようと思いました。

私は個人的にthe official formulasを現実に合わせて発行する問題がありました。私。短い文字列には小さなセルがあり、長い文字列には大きすぎるセルがあり、とりわけExcelに表示される値は、DocumentFormat.OpenXml.Spreadsheet.ColumnWidthプロパティに挿入した値より比例して小さくなりました。私の迅速な解決策は、ちょうど最小の幅を持つことでした。

私はに興味のxlsxファイルが自動生成され、それらが開かれるとすぐに素敵になりますので、最後にこれをしなければならなかったので、私はこれに見えた:

とにかく

は、ここでコメントですExcelで列のサイズを正確に設定するためのいくつかの問題があることがわかりました。

  1. 5つのピクセル(境界の1とそれぞれに2を追加すると言っスペックにもかかわらずhttp://groups.google.com/group/microsoft.public.office.developer.com.add_ins/browse_thread/thread/2fc33557feb72ab4/adaddc50480b8cff?lnk=raot

  2. を参照して、その代わりに、あなたはMeasureCharacterRangesを使用する必要がMeasureString使用するのでは意味し、正確な文字サイズを使用する必要がありますサイドマージン)Excelはボーダーに9 - 1、先行スペースに5、後続スペースに3を使用しているようです - 私はアクセシビリティアプリを使用してこれを見つけました。拡大鏡と自動私は実際にMeasureCharacterRangesまたはMeasureStringのいずれかを使用していないので、実際に私は、根本的なフォントメトリックに私の計算を基づかた列

にフィットするようにExcelを使用した後のピクセルを数えます。誰もが、その後フォントメトリックからこれを行うことに関心がある場合:

Width = Truncate({DesiredWidth} + 9/{MaxDigitWidth})/256

{MaxDigitWidthを} 96 DPI {DesiredWidth}があるで0..9桁の任意の最も近いピクセルに丸めた整数でありますすべての文字幅を合計した合計。各文字幅は、最も近い整数に丸められた96 dpiでの文字の幅です。各文字は総額ではなく丸められていることに注意してください。

関連する問題