Pokazywanie postów oznaczonych etykietą OpenXML. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą OpenXML. Pokaż wszystkie posty

środa, 29 grudnia 2010

OpenXML i odstępy pomiędzy liniami [PL]

Na temat Open XML już dłuższy czas nie pisałem. Dzisiaj chciałbym wrócić do tematu i napisać jak można ustawić odstępy między liniami w paragrafie w pliku Word'a (DOCX).

poniedziałek, 19 października 2009

Jak wyciągnąć grafiki i muzykę z prezentacji programu PowerPoint ?[PL]

Niedawno ktoś mnie zapytał, czy jest możliwe z istniejącej prezentacji programu PowerPoint wydobycie grafik, czy muzyki. Odpowiedziałem wtedy, że muszę sprawdzić czy poszukać,bo przecież łatwo coś do PowerPoint'a wkleić lub wstawić, ale nie można kliknąć na dowolnym obiekcie i wybrać: "Zapisz jako.."

Jak więc wyciągnąć jakąś grafikę, czy muzykę z prezentacji? Okazuje się to dość proste, jeżeli używamy PowerPoint'a 2007 (lub przynajmniej zapiszemy prezentację w tym formacie (OpenXML)). Można bowiem wtedy w prosty sposób dostać się do wszystkich zasobów dokumentu. Jak? Można to zrobić w podobny sposób jak to opisywałem jakiś czas temu na przykładzie pliku programu Word (docx). Zamieniamy rozszerzenie prezentacji (nie jest istotne czy jest to pptx, czy ppsx) na rozszerzenie typu zip, następnie wypakowujemy archiwum. W tym momencie powinniśmy uzyskać strukturę plików i katalogów podobną do poniższej:

plik.zip
|   [Content_Types].xml
|  +---docProps
|       app.xml
|       core.xml
|       thumbnail.jpeg
|      +---ppt
|   |   presentation.xml
|   |   presProps.xml
|   |   tableStyles.xml
|   |   viewProps.xml
|   |  |   +---media
|   |       audio1.wav
|   |       image1.png
|   |       image10.png
|   |       image11.png
|   |       image12.png
|   |       image13.png
|   |       image14.jpeg
|   |       image15.png
|   |       image16.png
|   |       image17.png
|   |       image18.png
|   |       image19.png
|   |      |   +---slideLayouts
|   |   |   slideLayout1.xml
|   |   |   slideLayout10.xml
|   |   |   slideLayout11.xml
|   |   |   slideLayout2.xml
|   |   |   slideLayout3.xml
|   |   |   slideLayout4.xml
|   |   |   slideLayout5.xml
|   |   |   slideLayout6.xml
|   |   |   slideLayout7.xml
|   |   |   slideLayout8.xml
|   |   |   slideLayout9.xml
|   |   |  |   |   \---_rels
|   |           slideLayout1.xml.rels
|   |           slideLayout10.xml.rels
|   |           slideLayout11.xml.rels
|   |           slideLayout2.xml.rels
|   |           slideLayout3.xml.rels
|   |           slideLayout4.xml.rels
|   |           slideLayout5.xml.rels
|   |           slideLayout6.xml.rels
|   |           slideLayout7.xml.rels
|   |           slideLayout8.xml.rels
|   |           slideLayout9.xml.rels
|   |          |   +---slideMasters
|   |   |   slideMaster1.xml
|   |   |  |   |   \---_rels
|   |           slideMaster1.xml.rels
|   |          |   +---slides
|   |   |   slide1.xml
|   |   |   slide2.xml
|   |   |   slide3.xml
|   |   |   slide4.xml
|   |   |   slide5.xml
|   |   |  |   |   \---_rels
|   |           slide1.xml.rels
|   |           slide2.xml.rels
|   |           slide3.xml.rels
|   |           slide4.xml.rels
|   |           slide5.xml.rels
|   |          |   +---theme
|   |       theme1.xml
|   |      |   \---_rels
|           presentation.xml.rels
|          \---_rels
      .rels

Teraz, jeżeli zajrzymy do katalogu "media" znajdziemy tam wszystkie wykorzystane w prezentacji obrazy i dźwięki. Proste prawda??

Co więcej można również wykorzystać opisany tu sposób do podmiany dowolnego obrazka na inny. Zadziwiające, że PowerPoint sam w sobie nie posiada funkcjonalności podmień obrazek w prezentacji, a przecież gdy wykonamy skomplikowaną animację, w której potrzebujemy podmienić jeden z wykorzystanych obrazów okazuje się bardzo problematyczne. Jak więc to zrobić? W tym celu rozpakowujemy prezentację, odnajdujemy interesujący nas obraz, podmieniamy go na nowy (pod tą samą nazwą), ponownie pakujemy prezentację.

Na koniec pozostaje nam jeszcze pytanie-dylemat, czy opisane tu czynności możemy wykonać, czy prawo autorskie nam na to pozwala, ale to już temat na inne rozwiązania i pozostawię to waszemu sumieniu.

Zainteresowanych dalszymi informacjami na temat formatu w jakim zapisywane są pliki przy pomocy Office 2007, czyli OpenXML, zachęcam do przeczytania artykułu: "Open XML - tworzymy dokument Word (docx)".

niedziela, 6 września 2009

Modyfikacja zawartości dokumentów DOCX (Część 1.: Wprowadzenie)[PL]

Promujkick it on DotNetKicks.com(English version)Shout it(English version)

W ramach kontynuacji tematyki związanej z Open XML Format SDK, chciałbym dzisiaj zwrócić uwagę kolejną funkcjonalność tego pakietu SDK, a mianowicie możliwość modyfikacji (edycji, dodawania komentarzy, itp. …) istniejących dokumentów.

W tym przykładzie załóżmy, że chcemy dodać na końcu istniejącego dokumentu docx nowy paragraf (zawierający znany tekst: "Hello World! ").Przykładowa funkcja, która może wytworzyć taki paragraf może wyglądać następująco:

private Paragraph CreateAndReturnHelloWorldParagraph()
{
   //Create paragraph
   Paragraph paragraph = new Paragraph();
   Run run_paragraph = new Run();
   // we want to put that text into the output document
   Text text_paragraph = new Text( "Hello World!" );
   //Append elements appropriately.
   run_paragraph.Append( text_paragraph );
   paragraph.Append( run_paragraph );
   return paragraph;
}

Teraz dodajmy nasz nowy paragraf (z tekstem "Hello World" na końcu istniejącego dokumentu.

Pierwszą czynnością, którą należy zrobić to otworzyć dokument, w tym celu można wykorzystać funkcję: "WordprocessingDocument.Open". Pierwszym argumentem funkcji jest nazwa pliku, natomiast drugi określa tryb dostępu (true jeśli plik ma być otworzony do odczytu I zapisu). Oczywiście ponieważ my będziemy modyfikować plik, dlatego należy ustawić tryb na odczyt i zapis (więc drugi argument powinien być równy "true").

Zauważmy, że użyty dokument powinien być zamknięty (nie może być aktualnie otworzony przez żadną inną aplikację (np. przez edytor Word), w przeciwnym razie otrzymamy wyjątek typu: System.IO.IOException ("The process cannot access the file XXX.docx' because it is being used by another process.").

Kolejną czynnością jaką musimy wykonać jest dodanie nowego paragra fu na końcu "body" modyfikowanego dokumentu (element: myWordprocessingDocument.MainDocumentPart.Document.Body)

Ostatnim krokiem jest zapis zamodyfikowanego dokumentu (mainDocumentPart.Document.Save();)

Proste, prawda?

Ostatecznie otrzymany kodu modyfikujący dokument może wyglądać następująco:

//Selecting a file
OpenFileDialog myopenFileDialog = new OpenFileDialog();
myopenFileDialog.Filter = "Word 2007 file (DOCX)|*.docx";
if ( myopenFileDialog.ShowDialog() == DialogResult.OK )
{
  //Open and manipulate docx
  using ( WordprocessingDocument myDoc = WordprocessingDocument.Open( myopenFileDialog.FileName, true ) )
  {
    //Access main part of document. 
    MainDocumentPart mainDocumentPart = myDoc.MainDocumentPart;
    //Creation of the new "hello world" paragraph
    Paragraph newelloWorldParagraph = CreateAndReturnHelloWorldParagraph();
    //Add new paragraph at the end of document body
    mainDocumentPart.Document.Body.Append( newelloWorldParagraph );
    //save the document
    mainDocumentPart.Document.Save();
  }
}
Promuj kick it on DotNetKicks.com(English version)Shout it(English version)

sobota, 5 września 2009

Modification of the content of the DOCX document (part 1: Getting started) [EN]

kick it on DotNetKicks.comShout it

The Open XML Format SDK supports not only the creation of the new document but allows also the modification of the existing document. In this short article I want to present the short overview of how to do it.

wtorek, 11 sierpnia 2009

Open XML - tworzymy dokument Word (docx) - Podsumowanie (1) [PL]

Ostatnio w ramach tego bloga pojawiło się trochę wpisów na temat formatu Open XML, tworzenia dokumentów dla Word (docx), języka WordProcessingML, tym razem postanowiłem przedstawić spis wspomnianych artykułów:

  1. Open XML Format SDK 2.0 - pierwsze wrażenia - gdzie znaleźć, jak zainstalować i jak napisać najprostszą aplikację
  2. Style w Open XML SDK - czyli podstawy formatowania tekstu i wykorzystaniu styli
  3. Tabele w Open XML Format SDK (DOCX) (czyli przygotowujemy tabliczkę mnożenia dla Workd 2007) - jak przygotować tabelę z wykorzystaniem SDK dla Open XML Format
  4. Kierunek: w głąb formatu "docx" - co tak na prawdę znajduje się w pliku DOCX
  5. Przyjrzyjmy się WordProcessingML wchodzącego w skład formatu OpenXML - jak wygląda ten OpenXML
  6. Na lewo, na prawo.... hej w Open XML - czyli jak sterować wyrównaniem tekstu (w stylach i paragrafach)

Wiem że te wpisy nie wyczerpują wszystkich zagadnień, a nawet można je nazwać zaledwie rzutem oka na ten temat, ale przy pomocy tego posta chciałbym usprawnić nawigację po tym blogu, tak aby łatwiej można było odnaleźć potrzebne informacje

Zapraszam do lektury!

sobota, 8 sierpnia 2009

Na lewo, na prawo.... hej w Open XML [PL]

"Na lewo, na prawo, w górę i w dół..." :-) - tym zabawowo(weselnym) akcentem zacznę tego posta, który ... dotyczyć będzie kolejnych zagadnień związanych z Open XML Format SDK.

A dlaczego? Gdyż chciałbym zająć się wyrównaniem tekstu: do lewej, do prawej, do środka, i wyjustowany.

Jak można więc ustawiać wyrównanie tekstu? W tym celu należy ustawić odpowiednie właściwości paragrafu dla stylu, który chcemy zmienić lub paragrafu w którym chcemy ustawić wyrównanie. Wykorzystujemy więc właściwość Justification klasy ParagraphProperties, której należy nadać wartość wchodzącą w skład elementu wyliczeniowego: JustificationValues Enumeration, o następujących elementach:

  • Center: Center (Equation)
  • CenterGroup: Centered as Group (Equations)
  • Left: Left Justification
  • Right: Right

Zakończmy więc teorię i przejdźmy do kodu, który będzie krótki i łatwy. Zakładając że na przykład chcemy wycentrować dany tekst (w paragrafie, bądź przy użyciu stylu) wystarczy wykonać następujący kod:

paragraph_or_style.Append( new ParagraphProperties(
    new Justification() { Val = JustificationValues.Center } ) );

Kod ten powoduje dodanie do dokumentu, napisanego w WordProcessingML, następującego kodu XML:

<w:jc w:val="center"/>

Tutaj ważna jest jeszcze jedna kwestia, a mianowicie odpowiednie formatowanie powinno być dodane do elementu paragrafu na początku i koniecznie przed dodaniem do niego tekstu, czyli np. oczekiwany efekt uzyskamy wykonując kod:

 Paragraph paragraph = new Paragraph();
 Run run_paragraph = new Run();
 // we want to put that text into the output document
 Text text_paragraph = new Text( "Hello World!" );
 //Append elements appropriately.
 run_paragraph.Append( text_paragraph );
 paragraph.Append( new ParagraphProperties(
    new Justification() { Val = JustificationValues.Center } ) );
 paragraph.Append( run_paragraph );

Natomiast tekst nie zostanie sformatowany, gdy do paragrafu najpierw został by dodany element Run, a dopiero później ParagraphProperties

środa, 5 sierpnia 2009

Przyjrzyjmy się WordProcessingML wchodzącego w skład formatu OpenXML [PL]

Chciałbym powrócić do tematyki związanej z tworzeniem dokumentów aplikacji MS Word (docx) zgodnych z formatem OpenXML z wykorzystniem pakietu Open XML Format SDK 2.0 i zająć się zawartością tworzonych dokumentów a dokładnie dokumentów napisanych w XML'u zgodnym z "językiem" WordProcessingML.

Proste Hello World!

Na początek zobaczmy jak wygląda proste "Hello World!" (przykładowy kod funkcji generującej taki dokument jest: tutaj)

<?xml version="1.0" encoding="utf-8"?> 
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"> 
  <w:body> 
   <w:p> 
   <w:r> 
   <w:t>Hello World!</w:t> 
   </w:r> 
   </w:p> 
  </w:body> 
</w:document> 

Jak widać w powyższym kodzie XML widać duże powiązanie pomiędzy kodem napisanym w C#, a powyższym. Zadeklarowany jest dokument (document = WordprocessingDocument) wewnąrz którego jest część Body (body), w niej znajduje się paragraf (p = Paragraph) z elementem typu Run (r) i odpowiednim tekstem (t = Text).

Style

W przypadku styli (przykładowy kod funkcji tutaj), generowane są dwa pliki, jeden zawierający definicję stylu:

<?xml version="1.0" encoding="utf-8"?> 
<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"> 
    <w:style w:styleId="MyHeading1"> 
        <w:name w:val="My Heading 1" /> 
        <w:basedOn w:val="Heading1" /> 
        <w:next w:val="Normal" /> 
        <w:rPr> 
        <w:color w:val="FF0000" /> 
        <w:rFonts w:ascii="Arial" /> 
        <w:b /> 
        <w:sz w:val="28" /> 
        </w:rPr> 
    </w:style> 
</w:styles>

oraz drugi z definicją z konkretnym dokumentem:

<?xml version="1.0" encoding="utf-8"?> 
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"> 
    <w:body> 
        <w:p> 
            <w:pPr> 
            <w:pStyle w:val="MyHeading1" /> 
            </w:pPr> 
            <w:r> 
            <w:t>This is Heading</w:t> 
            </w:r> 
        </w:p> 
    </w:body> 
</w:document> 

Jak widać w tym przypadku otrzymujemy kod WordProcessingML bardzo podobny do tego z poprzedniego przykładu, jednak  dodana została specjalna właściwość (pPr = ParagraphProperties), w której został wybrany odpowiedni styl (pStyle = ParagraphStyleId), który jest zdefiniowany w innym pliku.

Tabele

Ostatni przykład dotyczyć będzie tabeli (której tworzący ją kod jest tutaj):

<?xml version="1.0" encoding="utf-8" ?>
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
    <w:body>
        <w:tbl>
            <w:tblpr>
                <w:tblborders>
                    <w:top w:val="single" />
                    <w:left w:val="single" />
                    <w:bottom w:val="single" />
                    <w:right w:val="single" />
                    <w:insideh w:val="single" />
                    <w:insidev w:val="single" />
                </w:tblborders>
            </w:tblpr>
            <w:tr>
                <w:tc>
                    <w:p>
                        <w:r>
                            <w:t>Multiplication table</w:t>
                        </w:r>
                    </w:p>
                    <w:tcpr>
                        <w:gridspan w:val="11" />
                    </w:tcpr>
                </w:tc>
            </w:tr>
            <w:tr> 
            <w:tc>
                <w:p>
                    <w:r>
                        <w:t>*</w:t>
                    </w:r>
                </w:p>
            </w:tc> 
            <w:tc>
                <w:p>
                    <w:r>
                        <w:t>1</w:t>
                    </w:r>
                </w:p>
            </w:tc> 
            <!—- many cells and rows declarations --> 
            </w:tr>
        </w:tbl>
    </w:body>
</w:document>

Czyli mamy tutaj takie elementy jak tabela (tbl = Table ) z odpowiednimi właściwościami (tblpr = TableProperties ) i ramkami (tblborders = TableBorders ), w której znajdują się wiersze (tr = TableRow ) i kolumny (tc = TableCell ).

Podsumowanie

Jak widać na powyższych przykłach jest duży związek pomiędzy wykorzystywanymi elementami pakietu Open Document Format SDK a konkretnym elementami zapisywanymi w języku WordProcessingML, dlatego jeżli nie wiemy jak coś przygotować przy pomocy SDK, można zawsze przygotować odpowiedni plik przy pomocy edytora tekstu (np. Word), a następnie sprawdzić, co rzeczywiście zostało w nim utworzone (jeżeli ktoś nie wie jak to zrobić, to zapraszam do przeczytania posta:Kierunek: w głąb formatu "docx".

wtorek, 30 czerwca 2009

Kierunek: w głąb formatu "docx"

Chyba każdy kto próbował tworzyć "programistycznie" dokumenty docx (z wykorzystaniem OpenXML Format SDK lub bez SDK) na pewno spotkał się z problemem, że nie wiadomo jakich elementów użyć i jak je poustawiać, by uzyskać oczekiwany efekt. Niestety w dokumentacji opisane są co oznaczają poszczególne elementy, ale brakuje przykładów lub dokładniejszych opisów ich wykorzystania. Na szczęście jest pewna pomoc, którą można wykorzystać.

Przypomnijmy sobie jak zbudowany jest oparty o format Open XML? Przecież jest to zestaw plików (głównie XML), który następnie jest spakowany przy pomocy standardowego algorytmu zip, co w efekcie daje plik wynikowy. Dlatego można dowolnemu plikowi opartemu o ten format zmienić rozszerzenie (lub dodać kolejne) na zip, a następnie rozpakować zawartość tak spreparowanego archiwum. Tak na marginesie dodam, że w przypadku formatu rywala, czyli ODF (Open Document Format) idea pakowania algorytmem zip jest dokładnie taka sama.

Zobaczmy na przykład pliku Test.docx, któremu dodałem rozszerzenie zip i w efekcie otrzymałem plik Test.docx.zip, którego zawartość przedstawiona jest poniżej:

Test.docx.zip
|   [Content_Types].xml
|
+---docProps
|       app.xml
|       core.xml
|
+---word
|   |   document.xml
|   |   fontTable.xml
|   |   numbering.xml
|   |   settings.xml
|   |   styles.xml
|   |   webSettings.xml
|   |
|   +---media
|   |       image1.gif
|   |       image2.gif
|   |       image3.gif
|   |       image4.gif
|   |       image5.gif
|   |       image6.gif
|   |
|   +---theme
|   |       theme1.xml
|   |
|   \---_rels
|           document.xml.rels
|
\---_rels
        .rels

Najbardziej oczywiście interesującym nas plikiem będzie plik: word\document.xml, który będzie zawierał właściwy dokument. Plik ten w przypadku formatu Word 2007 (docx) jest zgodny z językiem WordProcessingML. Właśnie tam możemy znaleźć informacje na temat układu elementów XML, które w efekcie dają efekt, jaki widzimy podczas edycji tego dokumentu w edytorze Word.

Reasumując gdy nie wiemy jakich elementów użyć (i jak je poukładać) by uzyskać dokument Word o zadanej strukturze, można tą strukturę stworzyć przy pomocy edytora Word , a następnie "rozpakować" plik i podejrzeć jak to jest zrobione, Być może dla niektórych czytelników to banał, ale przyznam, że sam z tej metody korzystam. Jest ona prosta i skuteczna.

środa, 27 maja 2009

CodeProject: Creation of Word 2007 document using Open XML Format SDK

Ostatnio opublikowałem na portalu CodeProject artykuł na temat Open XML Format SDK i tworzenia przy jego pomocy dokumentu typu Word 2007.

http://www.codeproject.com/KB/office/OpenXML-SDK-HelloWorld.aspx

Zagadnienia poruszone w tym artykule, pokrywają się częściowo już z materiałem dostępnym na tym blogu, ale są i pewne dodatkowe treści (związane m.in. z samym językiem WordprocessingML).

Zapraszam do lektury.

sobota, 23 maja 2009

Tabele w Open XML Format SDK (DOCX) (czyli przygotowujemy tabliczkę mnożenia dla Workd 2007)

W poprzednich częściach przedstawione były zagadnienia związane z przygotowaniem prostego dokumentu oraz formatowaniem tekstu. W tej części będzie o tworzeniu tabel przy pomocy Open XML Format SDK.

Dzięki wygodnemu API jakie oferuje Open XML Format SDK tworzenie tabel jest bardzo proste i polega na dodaniu do głównego dokumentu elementu typu Table, w którym następnie osadzamy elementy typu TableRow i TableCell. Najprostszy przykład takiej tabeli wygląda następująco:

Body body = new Body();
Table table = new Table(new TableRow(new TableCell(
  new Paragraph(new Run(new Text("Hello World!"))))));
body.Append(table);

Tabliczka mnożenia

W tym przykładzie stworzymy tabelkę z tabliczką mnożenia (zupełnie taką jak w szkole ;) ):

Multiplication table

*

1

2

3

4

5

6

7

8

9

10

1

1

2

3

4

5

6

7

8

9

10

2

2

4

6

8

10

12

14

16

18

20

3

3

6

9

12

15

18

21

24

27

30

4

4

8

12

16

20

24

28

32

36

40

5

5

10

15

20

25

30

35

40

45

50

6

6

12

18

24

30

36

42

48

54

60

7

7

14

21

28

35

42

49

56

63

70

8

8

16

24

32

40

48

56

64

72

80

9

9

18

27

36

45

54

63

72

81

90

10

10

20

30

40

50

60

70

80

90

100

We wstępie pokazałem jak przygotować prostą tabelkę. W tym przykładzie też będziemy osadzać w sobie obiekty TableRow i TableCell, ale dodatkowo zadbamy jeszcze o krawędzie i ustawimy by komórka w pierwszym wierszu tabeli rozszerzona była na wszystkie kolumny poniżej.

Zacznijmy więc do ustawienia obramowania, dla całej tabeli ustawimy proste pojedyncze obramowanie, w tym celu wykorzystujemy klasy: TableProperties i TableBorders. Przykład poniżej:

Table table = new Table();
TableProperties tblPr = new TableProperties();
TableBorders tblBorders = new TableBorders();
tblBorders.TopBorder = new TopBorder();
tblBorders.TopBorder.Val = new EnumValue<BorderValues>(BorderValues.Single);
tblBorders.BottomBorder = new BottomBorder();
tblBorders.BottomBorder.Val =new EnumValue<BorderValues>(  BorderValues.Single);
tblBorders.LeftBorder = new LeftBorder();
tblBorders.LeftBorder.Val = new EnumValue<BorderValues>(BorderValues.Single);
tblBorders.RightBorder = new RightBorder();
tblBorders.RightBorder.Val = new EnumValue<BorderValues>(BorderValues.Single);
tblBorders.InsideHorizontalBorder = new InsideHorizontalBorder();
tblBorders.InsideHorizontalBorder.Val = BorderValues.Single;
tblBorders.InsideVerticalBorder = new InsideVerticalBorder();
tblBorders.InsideVerticalBorder.Val = BorderValues.Single;
tblPr.Append(tblBorders);
table.Append(tblPr);

Teraz zajmijmy się pierwszym wierszem i jego komórką, dla której musimy ustawić cechę by była rozszerzona na 11 kolumn znajdujących się niżej. W tym celu ustawiamy odpowiednie właściwości komórki (TableCellProperties), a dokładniej właściwość GridSpan.

tr = new TableRow();
tc = new TableCell(new Paragraph(new Run(new Text("Multiplication table"))));
TableCellProperties tcp=new TableCellProperties();
GridSpan gridSpan=new GridSpan();
gridSpan.Val=11;
tcp.Append(gridSpan);
tc.Append(tcp);
tr.Append(tc);

Teraz zostają już do wykonania tylko proste wyliczenia i ostatecznie otrzymujemy funkcję

public void HelloWorld_table(string docName)
{
  // Create a Wordprocessing document. 
  using (WordprocessingDocument myDoc = WordprocessingDocument.Create(docName, WordprocessingDocumentType.Document))
  {
    // Add a new main document part. 
    MainDocumentPart mainPart = myDoc.AddMainDocumentPart();
    //Create DOM tree for simple document. 
    mainPart.Document = new Document();
    Body body = new Body();
    Table table = new Table();
    TableProperties tblPr = new TableProperties();
    TableBorders tblBorders = new TableBorders();
    tblBorders.TopBorder = new TopBorder();
    tblBorders.TopBorder.Val = new EnumValue(BorderValues.Single);
    tblBorders.BottomBorder = new BottomBorder();
    tblBorders.BottomBorder.Val =new EnumValue(  BorderValues.Single);
    tblBorders.LeftBorder = new LeftBorder();
    tblBorders.LeftBorder.Val = new EnumValue(BorderValues.Single);
    tblBorders.RightBorder = new RightBorder();
    tblBorders.RightBorder.Val = new EnumValue(BorderValues.Single);
    tblBorders.InsideHorizontalBorder = new InsideHorizontalBorder();
    tblBorders.InsideHorizontalBorder.Val = BorderValues.Single;
    tblBorders.InsideVerticalBorder = new InsideVerticalBorder();
    tblBorders.InsideVerticalBorder.Val = BorderValues.Single;
    tblPr.Append(tblBorders);
    table.Append(tblPr);
    TableRow tr;
    TableCell tc;
    //first row - title
    tr = new TableRow();
    tc = new TableCell(new Paragraph(new Run(new Text("Multiplication table"))));
    TableCellProperties tcp=new TableCellProperties();
    GridSpan gridSpan=new GridSpan();
    gridSpan.Val=11;
    tcp.Append(gridSpan);
    tc.Append(tcp);
    tr.Append(tc);
    table.Append(tr);
    //second row 
    tr = new TableRow();
    tc = new TableCell();
    tc.Append(new Paragraph(new Run(new Text("*"))));
    tr.Append(tc);
    for (int i = 1; i <= 10; i++)
    {
      tr.Append(new TableCell(new Paragraph(new Run(new Text(i.ToString())))));
    }
    table.Append(tr);
    for (int i = 1; i <= 10; i++)
    {
      tr = new TableRow();
      tr.Append(new TableCell(new Paragraph(new Run(new Text(i.ToString())))));
      for (int j = 1; j <= 10; j++)
      {
        tr.Append(new TableCell(new Paragraph(new Run(new Text((i*j).ToString())))));
      }
      table.Append(tr);
    }
    //appending table to body
    body.Append(table);
    // and body to the document
    mainPart.Document.Append(body);
    // Save changes to the main document part. 
    mainPart.Document.Save();
  }
}
Promuj

niedziela, 10 maja 2009

Style w Open XML SDK

Promuj

Po przeczytaniu artykułu pt. "Open XML Format SDK 2.0 - pierwsze wrażenia", czytelnik wie już jak napisać prostą aplikację, która przy pomocy pakietu Open XML SDK i w języku C# tworzy prosty dokument typu Word 2007 (docx), który zawiera prosty tekst "Hello World!". Tym razem pójdziemy nieco dalej i dołożymy elementy związane z formatowaniem tekstu, czyli zajmiemy się stylami.

Załóżmy, że chcemy przygotować dokument, który będzie się składał z dwóch linijek tekstu. Pierwsza linijka będzie nagłówkiem akapitu, druga tekstem akapitu. To jak przygotować zwykły tekst (tak jak tutaj w drugiej linijce) pisałem o tym już wcześniej, tym razem napiszę jak przygotować tą pierwszą (odpowiednio sformatowaną) linijkę.

Pierwszą czynnością jaką należy wykonać, to trzeba dodać do tworzonego dokumentu część związaną z definicją stylów (dodajemy ją do głównego elementu dokumentu):

WordprocessingDocument myDoc = WordprocessingDocument.Create(documentFileName, WordprocessingDocumentType.Document)
MainDocumentPart mainPart = myDoc.AddMainDocumentPart();
StyleDefinitionsPart stylePart = mainPart.AddNewPart<StyleDefinitionsPart>();

Definiujemy teraz czcionkę (Font), którą chcemy wykorzystać (w tym przykładzie: czerwony i pogrubiony Arial, rozmiaru 28):

// we have to set the properties
RunProperties rPr = new RunProperties(); 
Color color = new Color() { Val = "FF0000" }; // the color is red
RunFonts rFont = new RunFonts();
rFont.Ascii = "Arial"; // the font is Arial
rPr.Append(color);
rPr.Append(rFont);
rPr.Append(new Bold()); // it is Bold
rPr.Append(new FontSize() { Val = 28 }); //font size (in 1/72  of an inch) 

Teraz czas na definicję stylu, będzie się on nazywać "My Heading 1", a jego identyfikator (używany później w dokumencie) to "MyHeading1". Oto definicja:

//creation of a style
Style style = new Style();
style.StyleId = "MyHeading1"; //this is the ID of the style
style.Append(new Name() { Val = "My Heading 1" }); //this is name
style.Append(new BasedOn() { Val = "Heading1" }); // our style based on Normal style
style.Append(new NextParagraphStyle() { Val = "Normal" }); // the next paragraph is Normal type
style.Append(rPr);//we are adding properties previously defined

W tym momencie nadszedł czas na dodanie stworzonego stylu do dokumentu i zapisanie części związanej ze stylami:

// we have to add style that we have created to the StylePart
stylePart.Styles = new Styles();
stylePart.Styles.Append(style);
stylePart.Styles.Save(); // we save the style part

Styl mamy już stworzony, teraz trzeba go przypisać do jakiegoś paragrafu. Słyży do tego klasa ParagraphProperties, której trzeba przypisać odpowiednie ParagraphStyleId. Przykład poniżej:

Paragraph heading = new Paragraph();
Run heading_run = new Run();
Text heading_text = new Text("This is Heading");
ParagraphProperties heading_pPr = new ParagraphProperties();
heading_pPr.ParagraphStyleId = new ParagraphStyleId() { Val = "MyHeading1" }; // we set the style
heading.Append(heading_pPr);
heading_run.Append(heading_text);
heading.Append(heading_run);

Teraz można już cieszyć się efektem naszych prac (przykład jest na załączonym rysunku), na sam koniec zamieszczę całą procedurę która generuje ten dokument:

private void HelloWorld_withStyle(string documentFileName)
{
  // Create a Wordprocessing document. 
  using (WordprocessingDocument myDoc = WordprocessingDocument.Create(documentFileName, WordprocessingDocumentType.Document))
  {
    // Add a new main document part. 
    MainDocumentPart mainPart = myDoc.AddMainDocumentPart();

    //Add new style part 
    StyleDefinitionsPart stylePart = mainPart.AddNewPart();
    // we have to set the properties
    RunProperties rPr = new RunProperties();
    Color color = new Color() { Val = "FF0000" }; // the color is red
    RunFonts rFont = new RunFonts();
    rFont.Ascii = "Arial"; // the font is Arial
    rPr.Append(color);
    rPr.Append(rFont);
    rPr.Append(new Bold()); // it is Bold
    rPr.Append(new FontSize() { Val = 28 }); //font size (in 1/72  of an inch) 
    //creation of a style
    Style style = new Style();
    style.StyleId = "MyHeading1"; //this is the ID of the style
    style.Append(new Name() { Val = "My Heading 1" }); //this is name
    style.Append(new BasedOn() { Val = "Heading1" }); // our style based on Normal style
    style.Append(new NextParagraphStyle() { Val = "Normal" }); // the next paragraph is Normal type
    style.Append(rPr);//we are adding properties previously defined
    // we have to add style that we have created to the StylePart
    stylePart.Styles = new Styles();
    stylePart.Styles.Append(style);
    stylePart.Styles.Save(); // we save the style part

    //Create Document tree for simple document. 
    mainPart.Document = new Document();
    //Create Body (this element contains other elements that we want to include
    Body body = new Body();
    //Create paragraph
    Paragraph paragraph = new Paragraph();
    Run run_paragraph = new Run();
    // we want to put that text into the output document
    Text text_paragraph = new Text("Hello World!");
    //Append elements appropriately.
    run_paragraph.Append(text_paragraph);
    paragraph.Append(run_paragraph);
    Paragraph heading = new Paragraph();
    Run heading_run = new Run();
    Text heading_text = new Text("This is Heading");
    ParagraphProperties heading_pPr = new ParagraphProperties();
    heading_pPr.ParagraphStyleId = new ParagraphStyleId() { Val = "MyHeading1" }; // we set the style
    heading.Append(heading_pPr);
    heading_run.Append(heading_text);
    heading.Append(heading_run);
    body.Append(heading);
    body.Append(paragraph);
    mainPart.Document.Append(body);
    // Save changes to the main document part. 
    mainPart.Document.Save();
  }
}
Promuj

poniedziałek, 27 kwietnia 2009

Open XML Format SDK 2.0 - pierwsze wrażenia

Microsoft w kwietniu tego roku opublikował kolejną wersję pakietu SDK do manipulacji dokumentów w formacie OpenXML. Pakiet ten ma za zadanie ułatwić tworzenie i edycję plików w formacie OpenXML z poziomu języka programowania (np. C#), automatyzując standardowe operacje jakie zwykle implementować muszą programiści tworzący aplikacje wykorzystujące ten format. Pakiet można pobrać ze stron Microsoft'u: http://www.microsoft.com/downloads/details.aspx?FamilyID=C6E744E5-36E9-45F5-8D8C-331DF206E0D0&displaylang=en.

Gdzie szukać informacji na temat Open XML i pakietu SDK?

Pierwszy program ("Hello Word" w OpenXML)

Do projektu należy dodać następujące referencje:
  • DocumentFormat.OpenXml
  • WindowsBase
W kodzie dołączamy następujące przestrzenie nazw:
  • DocumentFormat.OpenXml;
  • DocumentFormat.OpenXml.Packaging;
  • DocumentFormat.OpenXml.Wordprocessing;
Teraz funkcja realizująca proste "Hello World" w OpenXML:
private void HelloWorld(string documentFileName)
{
  // Create a Wordprocessing document.
  using (WordprocessingDocument myDoc = WordprocessingDocument.Create(documentFileName, WordprocessingDocumentType.Document))
  {
    // Add a new main document part.
    MainDocumentPart mainPart = myDoc.AddMainDocumentPart();
    //Create Document tree for simple document.
    mainPart.Document = new Document();
    //Create Body (this element contains other elements that we want to include
    Body body = new Body();
    //Create paragraph
    Paragraph paragraph = new Paragraph();
    Run run_paragraph = new Run();
    // we want to put that text into the output document
    Text text_paragraph = new Text("Hello World!");
    //Append elements appropriately.
    run_paragraph.Append(text_paragraph);
    paragraph.Append(run_paragraph);
    body.Append(paragraph);
    mainPart.Document.Append(body);
    // Save changes to the main document part.
    mainPart.Document.Save();
  }
}
Powyższa funkcja tworzy dokument w pliku podanym przez użytkownika. Do dokumentu dodany jest paragraf który zawiera tekst "Hello World!". W ostatnim kroku dokument jest zapisywany. A jak tą funkcję wykorzystać? Poniższy przykład pyta użytkownika o plik, do którego ma być zapisany tekst, wywołuje wcześniej stworzoną funkcję i otwiera przygotowany plik przy pomocy Word (lub innej ustawionej w systemie przeglądarki plików docx).
SaveFileDialog mySaveFileDialog=new SaveFileDialog();
mySaveFileDialog.Filter = "Word 2007 file (DOCX)|*.docx";
//save dialog display:
if (mySaveFileDialog.ShowDialog() == DialogResult.OK)
{
  //call creation of HellowWord document
  HelloWorld(mySaveFileDialog.FileName);
  // let's open this deocument in Word:

  Process.Start(mySaveFileDialog.FileName);
}

Podsumowanie

Na pierwszy rzut oka, pakiet ten oferuje bardzo wygodną możliwość manipulacji plikami zgodnymi z OpenXML. Postaram się w przyszłych postach opisać bardziej zaawansowane jego możliwości.

Posty powiązane / Related posts