2011-10-10 11 views
9

Spędziłem wiele godzin próbując określić formułę do przekonwertowania pikseli .NET na szerokość kolumny programu Excel przy użyciu formatu OpenXML. Używam EPPlus do generowania dokumentów xml. Próbuję określić szerokość kolumny, która ma mieć rozmiar automatyczny. Dostaję liczbę pikseli, mierząc ciąg, a następnie próbując przekonwertować go na szerokość kolumny dla OpenXML, który jest mierzony według znaków.Formuła do konwersji pikseli .NET do szerokości Excela w formacie OpenXML

czytałem dokumentacji Microsoftu, w jaki sposób przekształcić go i starał formułę Sugerują one, ale nie jest nawet blisko bycia dokładny:

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

Oto mój kod wykorzystując swoją formułę:

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; 
    } 

Wszelkie pomysły?

+0

Jeśli kolumna ma mieć automatyczne rozmiary, dlaczego nie zastosować atrybutu najlepszego dopasowania określonego w połączonej witrynie MSDN? – PeteT

+0

Próbowałem już tego. Po ustawieniu BestFit na True, a następnie otwarciu arkusza kalkulacyjnego, kolumny nie są odpowiednio dobrane. –

+0

Pixel-to-EMU to (piksel * 12700). Nie spodziewałbym się, że szerokość kolumn będzie w pikselach. Wypróbuj EMU. –

Odpowiedz

16

Najpierw musimy ustalić, jak Excel robi konwersję (jak ręcznie zmienić rozmiar w aplikacji Excel):

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

zastrzeżenie: Wzory nie działają na 0 (zero) szerokość lub Piksele.
Dla tych scenariuszy użyj instrukcji "if", aby sprawdzić, czy zero i zero.

Zarzuciło mi to również na pętlę. Zamiast próbować znaleźć Pixels per Width, przyjrzałem się różnicy w pikselach między każdą liczbą całkowitą w całej szerokości i stwierdziłem, że zawsze było 7. Wyjątkiem była szerokość od 0 do 1; gdzie było 12 pikseli dla szerokości 1,00. Stamtąd udało mi się wymyślić powyższe formuły, łatwe-peasy.

Teraz te liczby utrzymują się w świecie programu Excel, ale jeśli ustawiasz szerokości kolumn bezpośrednio w dokumencie OpenXML, jest to nieco inna historia. Oto dlaczego: W dokumentacji, do której prowadzi link, jest to około 5 pikseli:

Dostępne są 4 piksele wypełnienia marginesów (po dwa z każdej strony) oraz 1 piksel dla linii siatki.

Wszystko to oznacza, że ​​program Excel zakłada, że ​​uwzględniłeś te 5 pikseli w podanych szerokościach. Kiedy otworzysz dokument w programie Excel i zmienisz rozmiar kolumn, zobaczysz, że szerokość jest o 5 pikseli mniejsza niż ustawiona.

Aby dostosować do tego można zaktualizować formuły następująco:

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

ten odbierze tytuł zapytanie:
Formuły przekonwertować .NET pikseli szerokości Excel w formacie OpenXML

Jeśli chcesz wiedzieć, jak obliczyć szerokość kolumny, aby automatycznie dopasować kolumnę na podstawie zawartości (i czcionki) pojedynczej komórki, to jest zupełnie inne pytanie. Formuły dostarczone przez podany przez Ciebie link Microsoft nie będą działać. Wpisz 10 okresów w jednej komórce i 10 kapitałowych M w innej kolumnie. Zobaczysz, że automatyczne dopasowywanie daje odpowiednio 41 pikseli i 129 pikseli. Formuły dostarczone przez ms nie uwzględniają szerokości poszczególnych znaków. Innymi słowy; wysłali cię na dziką pogoń za gęsi.

Jedynym sposobem na automatyczne dopasowanie kolumny jest przeskanowanie każdego wiersza w kolumnie i obliczenie szerokości tekstu na podstawie użytych znaków i czcionki. Możesz użyć czegoś podobnego do tego, co znalazłem: here. Następnie weź maksymalną wartość tej wartości, a pad 5. Pomoże ci to uniknąć przetwarzania arkuszy kalkulacyjnych w środowisku sieciowym, ponieważ możesz eksportować setki tysięcy wierszy z dziesiątkami kolumn - masz pomysł. Najlepszym rozwiązaniem jest ustawienie najlepszej szerokości odgadnięcia kolumn i przeszkolenie użytkowników w zakresie automatycznego dopasowania z programu Excel.

poważaniem
"The Common Man"


Edit - 26.10.2011:

Bo czuję się wspaniałomyślny, oto przykład jak uzyskać przybliżona szerokość dla twojej kolumny. Wolałbym unikać tego dla wszystkich wierszy w kolumnie, więc oprzyjmy naszą szerokość (domyślnie) na wartości w komórce nagłówka. Poniżej możesz się dowiedzieć, jak to zrobić, korzystając z przykładu, do którego wcześniej dołączyłem. Uwaga: są to przybliżenia, ale wystarczająco zbliżone.

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. 

Zastrzeżenie: Jeśli użyjesz tego kodu w tym samym miejscu używasz OPENXML, to może trzeba usunąć „za pomocą” dla System.Drawing iw pełni zakwalifikować „Czcionka” i „fontStyle” jako System.Drawing.Font i System.Drawing.FontStyle. W przeciwnym razie Twój kompilator może pomylić te klasy z przynależnością do DocumentFormat.OpenXml.Spreadsheet.

+0

Znalazłem pierwszą formułę, którą zasugerowałeś, aby była najdokładniejsza, choć wciąż niedokładna. Muszę to trochę zmodyfikować, aby "zgadnąć" najlepiej jak powiedziałeś. –

+0

Czy widzisz kod, który opublikowałem na dole pod moją edycją? Używam tego i działa idealnie na moje potrzeby (podaj lub weź kilka pikseli, ale nie na tyle, aby pokazać znaki funta lub klip). Prawdopodobnie zmodyfikuję mój kod, aby zeskanować nagłówek i pierwsze 20 wierszy dla maksymalnej szerokości (ponieważ to właśnie zobaczy użytkownik po pierwszym otwarciu dokumentu). Jeśli chodzi o pierwszą formułę, to jest ona bardzo dokładna przy obliczaniu Pikseli do szerokości OpenXML, która da identyczną liczbę pikseli podczas otwierania dokumentu Excela (pamiętaj, aby ustawić tę samą nazwę czcionki, Boldness i Rozmiar). Dzięki za punkty! – MikeTeeVee

Powiązane problemy