2011-10-10 93 views
9

我花了很多時間試圖確定使用OpenXML格式將.NET像素轉換爲Excel列寬的公式。我正在使用EPPlus生成xml文檔。我正在嘗試確定要自動調整大小的列的寬度。我通過測量字符串來獲取像素的數量,然後嘗試將其轉換爲OpenXML的列寬度,我認爲這是以字符度量的。將.NET像素轉換爲OpenXML格式的Excel寬度的公式

我讀過微軟如何將其轉換並嘗試他們提出的公式文件,但它甚至還沒有接近是準確的:

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

Pixel-to-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個像素的邊距填充(每邊兩個),另外還有1個網格線的像素填充。

現在,所有這意味着是Excel的假設您在這5個像素爲您提供的寬度已經分解。當您在Excel中打開文檔並調整列大小時,您會看到寬度比您設置的寬度小5個像素。

要對此進行調整,你可以作如下更新公式:

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

這個回答你的問題的標題:
公式到.NET的像素轉換到Excel寬度OpenXML格式

如果您想知道如何根據單個單元格的內容(和字體)自動調整列寬,那麼這是完全不同的問題。您提供的微軟鏈接提供的公式不起作用。在一個單元中輸入10個週期,在另一個列中輸入10個資本-M。你會看到自動適合分別給你41個像素和129個像素。由ms提供的公式不考慮單個字符的寬度。換一種說法;他們派你去野蠻追逐。

自動適合一列中的唯一方法是通過在列中的每一行進行掃描,並計算基於所使用的字符和字體的文本的寬度。你會用我發現的東西here。然後利用這一最大值和墊5.在網絡環境中處理的電子表格時,因爲你可能會被出口幾十萬行幾十列的我會避免這種做法 - 你的想法。最好的方法是爲列設置一個最佳猜測寬度,並訓練用戶如何從excel自動調整。

真誠,
普通人


編輯 - 10/26/2011:

因爲我感覺大方,這裏有一個如何得到一個例子近似寬度爲您列。我寧願避免爲列中的所有行執行此操作,因此我們只需將寬度(默認情況下)放在標題單元格中的值上即可。下面是你如何使用我之前鏈接的例子來做到這一點。注意:這些是近似值,但足夠接近。

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,那麼你可能需要刪除「使用」爲System.Drawing中,完全符合「字體」和「FontStyle」作爲System.Drawing.Font和System.Drawing.FontStyle。否則,您的編譯器可能會將這些類誤認爲屬於DocumentFormat.OpenXml.Spreadsheet。

+0

我發現你建議是最準確的第一個公式,但仍不夠準確。正如你所說,我必須稍微修改一下以做出「最佳猜測」。 –

+0

您是否看到我在我的編輯底部張貼的代碼?我使用它,它適用於我的需要(給或帶幾個像素,但不足以顯示磅符號或剪輯文本)。我可能會修改我的代碼來掃描標題和前20行以獲取最大寬度(因爲這是用戶第一次打開文檔時首次看到的內容)。作爲用於第一個公式是在計算像素分爲處理OpenXML寬度打開Excel文檔時,將產生的像素的相同確切數目完全準確的(記得要設置相同的字體的名稱,粗體,和大小)。感謝您的積分! – MikeTeeVee