2011-10-10 64 views
9

OpenXML形式を使用して.NETピクセルをExcelの列幅に変換する式を決定するのに、何時間も費やしました。私はEPPlusを使ってXML文書を生成しています。私は、オートサイズにする列の幅を決定しようとしています。文字列を測定し、その文字列をOpenXMLの列幅に変換しようとすると、ピクセル数が増えていると思います。OpenXML形式で.NETピクセルをExcelの幅に変換する式

私はそれを変換する方法については、Microsoftのマニュアルを読み、彼らが提案式を試してみましたが、それは正確であることにさえ近くないました:

http://msdn.microsoft.com/en-us/library/documentformat.openxml.spreadsheet.column.aspx

は、ここで彼らの式を使用して私のコードです:

public double GetCharacterWidth(string Text, Font f, Graphics g) 
    { 
     float MaxDigitWidth = g.MeasureString("0", f).Width; 
     float Pixels = g.MeasureString(Text, f).Width; 

     return ((Pixels - 5)/MaxDigitWidth * 100 + 0.5)/100; 
    } 

+0

自動サイズ設定される列の場合、リンクされたMSDNで指定されているように最適な属性を使用しないのはなぜですか? – PeteT

+0

私はすでにそれを試みました。 BestFitをTrueに設定してスプレッドシートを開くと、列のサイズが適切に調整されません。 –

+0

ピクセルからEMUまで(ピクセル* 12700)です。私は列の幅がピクセル単位であるとは思わないでしょう。 EMUを試してみてください。 –

答えて

16

我々はExcelが変換を行う方法を確立する必要が最初に(私たちは手動でExcelアプリケーション内のサイズを変更すると):

//Use 7d to promote to double, otherwise int will truncate. 
ExcelWidth = (Pixels - 12)/7d + 1;//From pixels to inches. 

警告:式が0のために動作しない(ゼロ)幅またはピクセル。
これらのシナリオでは、 "if"ステートメントを使用してゼロをチェックしてゼロを返します。

それもループのために私を投げた。幅ごとのピクセル数を調べる代わりに、各幅の整数間のピクセルの差を調べ、それが常に7であることを見出しました。例外は0〜1幅でした。幅1.00のピクセルは12ピクセルでした。そこから、私は簡単なピースの上の式を考え出すことができました。

これらの数値はExcelの世界では上書きされますが、列幅をOpenXmlドキュメントに直接設定している場合は、少し違ったものになります。その理由は次のとおりです。リンク先のドキュメントには、5ピクセルについての説明があります。

マージンパディングの4ピクセル(両側に2つ)とグリッドラインの1ピクセルのパディングがあります。

ここで意味するのは、エクセルでは、あなたが提供しているこれらの5ピクセルを考慮していると仮定しています。ドキュメントを開いて列のサイズを変更すると、幅は設定した幅よりも5ピクセル小さいことがわかります。次のように

これを調整するには、数式を更新することができます。

//Use 7d to promote to double, otherwise int will truncate. 
OpenXmlWidth = (Pixels - 12 + 5)/7d + 1;//From pixels to inches. 

これはあなたの質問のタイトル答え:
式OpenXML形式でExcel幅に.NETピクセルを変換するための

1つのセルの内容(およびフォント)に基づいて列を自動フィットするための列幅の近似値を計算する方法を知りたい場合は、まったく異なる質問です。あなたが提供したマイクロソフトのリンクによって提供される数式は機能しません。 1つのセルに10の期間、もう1つの列に10の資本金を入力します。オートフィットではそれぞれ41ピクセルと129ピクセルが得られます。 msによって提供される式は、個々の文字の幅を考慮しません。言い換えると;彼らは野生のガチョウの追跡にあなたを送った。

列を自動調整する唯一の方法は、列内のすべての行をスキャンして、使用する文字とフォントに基づいてテキストの幅を計算することです。あなたは私が見つけたもののようなものを使うでしょうhere。そして、それとパッドの最大値を5とします。ウェブ環境でスプレッドシートを処理するときは、数十万行をエクスポートすることができるので、このアプローチは避けます。最適な方法は、列の最適な幅を設定し、ユーザーがExcelから自動的にフィットする方法を習得することです。敬具


"コモンマン"


編集 - 2011年10月26日:

私は寛大な感じているので、ここで取得する方法の例ですおおよその列の幅はです。私は列内のすべての行に対してこれを行うことを避けたいので、ヘッダーセルの値にデフォルトで幅を設定してみましょう。以下は私が先にリンクした例を使ってこれを行う方法です。注:これらは近似値ですが、十分に近いです。

using System.Drawing; 
using System.Windows.Forms;//Add Reference. Test on webserver first. 
Font font = new Font("Calibri", 11.0f, FontStyle.Regular); 
string header = "Hello There World!"; 
int pxBaseline = TextRenderer.MeasureText("__", font).Width; 
int pxHeader = TextRenderer.MeasureText("_" + header + "_"), font).Width; 
int pxColumnWidth = pxHeader - pxBaseline + 5;//Pad with 5 for Excel. 

警告:あなたはのOpenXmlを使用している同じ場所にこのコードを使用した場合、あなたは「フォント」と「のfontStyleを」System.Drawing用の「使用」を削除し、完全に修飾する必要があるかもしれませんSystem.Drawing.FontおよびSystem.Drawing.FontStyleとして宣言します。そうしないと、コンパイラはこれらのクラスをDocumentFormat.OpenXml.Spreadsheetに属するものと間違えることがあります。

+0

私はあなたが最も正確であると提案した最初の数式を見つけましたが、それでも十分正確ではありません。あなたが言ったように、私はそれを少し修正して "最高の推測"をしなければなりません。 –

+0

私の編集の下部に投稿したコードを見ましたか?私はそれを使用して、それは私のニーズに完璧に動作します(ポンド記号やクリップテキストを表示するのに十分ではありません。私はおそらくヘッダーと最大幅の最初の20行をスキャンするようにコードを変更するでしょう(これは、ユーザーが最初に文書を開くときに最初に表示されるためです)。最初の公式については、OpenXML-WidthへのPixelsの計算では、Excelドキュメントを開くときに同じ正確なピクセル数を得ることができます(同じフォントの名前、太字、およびサイズを忘れないでください)。ポイントをありがとう! – MikeTeeVee