About Me

My photo
Ireland
Hello, my name is Cathal Coffey. I am best described as a hybrid between a developer and an adventurer. When I am not behind a keyboard coding, I am hiking and climbing the beautiful mountains of my home country Ireland. I am a full time student studying Computer Science & Software Engineering at the National University of Ireland Maynooth. I am finishing the final year of a 4 year degree in September 2009. I am the creator of an open source project on codeplex.com called DocX. At the moment I spend a lot of my free time advancing DocX and I enjoy this very much. My aim is to build a community around DocX and add features based on requests from this community. I really enjoy hearing about how people are using DocX in their work\personal projects. So if you are one of these people, please send me an email. Cathal coffey.cathal@gmail.com

Monday, June 28, 2010

DocX version 1.0.0.10

This version of DocX contains support for Headers and Footers.
There are a few different options to choose from.

1) You can have a default Header and Footer for the entire document.
2) You can have a different Header and Footer for the first page.
3) You can have a different Header and Footer for odd and even pages.

The first code example generates a document with a default Header and Footer that is applied to all pages.

Default Header and Footer
  1. // Create a new document.
  2. using (DocX document = DocX.Create(@"Test.docx"))
  3. {
  4.     // Add Header and Footer support to this document.
  5.     document.AddHeaders();
  6.     document.AddFooters();
  7.  
  8.     // Get the default Header for this document.
  9.     Header header_default = document.Headers.odd;
  10.  
  11.     // Get the default Footer for this document.
  12.     Footer footer_default = document.Footers.odd;
  13.  
  14.     // Insert a Paragraph into the default Header.
  15.     Paragraph p1 = header_default.InsertParagraph();
  16.     p1.Append("Hello Header.").Bold();
  17.  
  18.     // Insert a Paragraph into the document.
  19.     Paragraph p2 = document.InsertParagraph();
  20.     p2.AppendLine("Hello Document.").Bold();
  21.  
  22.     // Insert a Paragraph into the default Footer.
  23.     Paragraph p3 = footer_default.InsertParagraph();
  24.     p3.Append("Hello Footer.").Bold();
  25.     
  26.     // Save all changes to this document.
  27.     document.Save();
  28. }// Release this document from memory.

The code directly above will generate a document that looks like the image below.

Untitled2 
The second code example generates a document which has a different Header and Footer for the first page. All other pages use the default Header and Footer.

First Header and Footer
  1. // Create a new document.
  2. using (DocX document = DocX.Create(@"Test.docx"))
  3. {
  4.     // Add Header and Footer support to this document.
  5.     document.AddHeaders();
  6.     document.AddFooters();
  7.  
  8.     // Get the first Header for this document.
  9.     Header header_first = document.Headers.first;
  10.  
  11.     // Get the first Footer for this document.
  12.     Footer footer_first = document.Footers.first;
  13.  
  14.     // Insert a Paragraph into the first Header.
  15.     Paragraph p1 = header_first.InsertParagraph();
  16.     p1.Append("Hello First Header.").Bold();
  17.  
  18.     // Insert a Paragraph into the document.
  19.     Paragraph p2 = document.InsertParagraph();
  20.     p2.AppendLine("Hello First page.");
  21.     
  22.     // Create a second page to show that only the first has a header and footer.
  23.     p2.InsertPageBreakAfterSelf();
  24.  
  25.     // Insert a Paragraph after the page break.
  26.     Paragraph p3 = document.InsertParagraph();
  27.     p3.AppendLine("Hello Second page.");
  28.  
  29.     // Insert a Paragraph into the first Footer.
  30.     Paragraph p4 = footer_first.InsertParagraph();
  31.     p4.Append("Hello First Footer.").Bold();
  32.  
  33.     // Force the first page to have a different Header and Footer.
  34.     document.DifferentFirstPage = true;
  35.  
  36.     // Save all changes to this document.
  37.     document.Save();
  38. }// Release this document from memory.

The code directly above will generate a document that looks like the image below. Notice that the second page has an empty Header and Footer, this will also be the same for all proceeding pages.

Untitled3

The third code example generates a document which has a different Header and Footer for odd and even pages.

Odd and Even Header and Footer
  1. // Create a new document.
  2. using (DocX document = DocX.Create(@"Test.docx"))
  3. {
  4.     // Add Header and Footer support to this document.
  5.     document.AddHeaders();
  6.     document.AddFooters();
  7.  
  8.     // Get the odd and even Headers for this document.
  9.     Header header_odd = document.Headers.odd;
  10.     Header header_even = document.Headers.even;
  11.  
  12.     // Get the odd and even Footer for this document.
  13.     Footer footer_odd = document.Footers.odd;
  14.     Footer footer_even = document.Footers.even;
  15.  
  16.     // Insert a Paragraph into the odd Header.
  17.     Paragraph p1 = header_odd.InsertParagraph();
  18.     p1.Append("Hello Odd Header.").Bold();
  19.  
  20.     // Insert a Paragraph into the even Header.
  21.     Paragraph p2 = header_even.InsertParagraph();
  22.     p2.Append("Hello Even Header.").Bold();
  23.  
  24.     // Insert a Paragraph into the document.
  25.     Paragraph p3 = document.InsertParagraph();
  26.     p3.AppendLine("Hello First page.");
  27.     
  28.     // Create a second page to show that even and odd pages have different headers and footers.
  29.     p3.InsertPageBreakAfterSelf();
  30.  
  31.     // Insert a Paragraph after the page break.
  32.     Paragraph p4 = document.InsertParagraph();
  33.     p4.AppendLine("Hello Second page.");
  34.  
  35.     // Insert a Paragraph into the odd Footer.
  36.     Paragraph p5 = footer_odd.InsertParagraph();
  37.     p5.Append("Hello Odd Footer.").Bold();
  38.  
  39.     // Insert a Paragraph into the even Footer.
  40.     Paragraph p6 = footer_even.InsertParagraph();
  41.     p6.Append("Hello Even Footer.").Bold();
  42.  
  43.     // Force odd & even pages to have different Headers and Footers.
  44.     document.DifferentOddAndEvenPages = true;
  45.  
  46.     // Save all changes to this document.
  47.     document.Save();
  48. }// Release this document from memory.

The code directly above will generate a document that looks like the image below. Note that the first page has a different header and footer than the second.

Untitled4

It is of course possible to create a document with a different header and footer for odd, even and the first page. You just need to set the following two properties to true.

// Force the first, odd & even pages to have different Headers and Footers.
document.DifferentOddAndEvenPages = true;
document.DifferentFirstPage = true;

This version of DocX does not support page numbering inside Headers and Footers. This feature will require much more development time due to the shear number of options available for numbering. I hope to add this feature in the near future.

Happy coding,
Cathal

Monday, June 14, 2010

Cathal: Why did you create DocX?

Before I created the OpenSource library “DocX”, there were two methods by which a .docx document could be generated programmatically. This blog post demonstrates each method in turn by generating a simple HelloWorld document. 

After experiencing both methods for document creation I hope you will agree that DocX is a interesting alternative. DocX was designed with simplicity in mind. It dose not require the user to have any knowledge of how .docx documents are stored or organised internally.

Method 1: HelloWorld using Office Interop

Make sure that you have added a reference to

1) Microsoft.Office.Interop.Word (version 12.0.0.0)

image

OfficeInterop HelloWorld
  1. using System;
  2. using Microsoft.Office.Interop.Word;
  3. using System.Reflection;
  4. using System.IO;
  5.  
  6. namespace OfficeInterop
  7. {
  8.     class Program
  9.     {
  10.         static void Main(string[] args)
  11.         {
  12.             // Get the path of the executing assembly.
  13.             string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
  14.  
  15.             // The location to save the file.
  16.             Object oSaveAsFile = (Object)(path + @"\Test.docx");
  17.  
  18.             // Object of Missing "Null Value".
  19.             Object oMissing = System.Reflection.Missing.Value;
  20.  
  21.             // Object of false.
  22.             Object oFalse = false;
  23.  
  24.             // Create object of Word and Document.
  25.             Application oWord = new Application();
  26.             Document oWordDoc = new Document();
  27.  
  28.             // Don't display Word.
  29.             oWord.Visible = false;
  30.  
  31.             // Add a new document.
  32.             oWordDoc = oWord.Documents.Add(ref oMissing, ref oMissing, ref oMissing, ref oMissing);
  33.             
  34.             // Enter some text with the font Arial Black.
  35.             oWord.Selection.Font.Name = "Arial Black";
  36.             oWord.Selection.TypeText("Hello World");
  37.  
  38.             // Save the document.
  39.             oWordDoc.SaveAs
  40.             (
  41.                 ref oSaveAsFile, ref oMissing, ref oMissing, ref oMissing,
  42.                 ref oMissing, ref oMissing,ref oMissing, ref oMissing, ref oMissing,
  43.                 ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing,
  44.                 ref oMissing, ref oMissing
  45.             );
  46.  
  47.  
  48.             // Close the file.
  49.             oWordDoc.Close(ref oFalse, ref oMissing, ref oMissing);
  50.              
  51.             // Quit Word.exe
  52.             oWord.Quit(ref oMissing, ref oMissing, ref oMissing);
  53.         }
  54.     }
  55. }

 

Method 2: HelloWorld using the OOXML SDK

Make sure that you have added a reference to both

1) DocumentFormat.OpenXml (version 2.0.5022.0)
2) WindowsBase (version 3.0.0.0)

image

OOXML HelloWorld
  1. using DocumentFormat.OpenXml.Packaging;
  2. using DocumentFormat.OpenXml.Wordprocessing;
  3. using DocumentFormat.OpenXml;
  4.  
  5. namespace OOXML
  6. {
  7.     class Program
  8.     {
  9.         static void Main(string[] args)
  10.         {
  11.             // Create a package.
  12.             WordprocessingDocument doc =
  13.             WordprocessingDocument.Create
  14.             (
  15.                 @"Test.docx",
  16.                 WordprocessingDocumentType.Document
  17.             );
  18.  
  19.             // Create a main document part and add it to the package.
  20.             MainDocumentPart mainPart = doc.AddMainDocumentPart();
  21.             mainPart.Document = new Document();
  22.             
  23.             // Create some content.
  24.             Text textFirstLine = new Text("Hello World");
  25.             Run run = new Run(textFirstLine);
  26.             Paragraph para = new Paragraph(run);
  27.            
  28.             // Apply a font.
  29.             RunProperties runProp = new RunProperties();
  30.             RunFonts runFont = new RunFonts();
  31.             runFont.Ascii = "Arial Black";
  32.             runProp.Append(runFont);
  33.             run.PrependChild<RunProperties>(runProp);
  34.             // Add the content into the document.
  35.             Body body = new Body(para);
  36.             mainPart.Document.Append(body);
  37.             
  38.             /* Save and close */
  39.             mainPart.Document.Save();
  40.             doc.Close();
  41.         }
  42.     }
  43. }

HelloWorld using DocX

Make sure that you have added a reference to

1) DocX (version 1.0.0.9)
2) System.Drawing (version 2.0.0.0)

image

DocX HelloWorld
  1. using System;
  2. using Novacode;
  3. using System.Drawing;
  4.  
  5. namespace DocXHelloWorld
  6. {
  7.     class Program
  8.     {
  9.         static void Main(string[] args)
  10.         {
  11.             using (DocX document = DocX.Create("Test.docx"))
  12.             {
  13.                 // Add a new Paragraph to the document.
  14.                 Paragraph p = document.InsertParagraph();
  15.                 
  16.                 // Append some text.
  17.                 p.Append("Hello World").Font(new FontFamily("Arial Black"));
  18.  
  19.                 // Save the document.
  20.                 document.Save();
  21.             }
  22.         }
  23.     }
  24. }

Thursday, June 10, 2010

Fluid Paragraph creation with Append

DocX v1.0.0.9 makes Paragraph creation even easier. The original idea of using Append in this manor came from a DocX user Morten Bjerre. Once again Morten I would like to say thank you for your contribution.

The below code creates a document with the following content.

  1. A Picture
  2. A Hyperlink
  3. Different fonts
  4. Different text styles

I hope you will agree that Append() and its variants [AppendLine(), AppendPicture() and AppendHyperlink()] make the creation of Paragraphs flow in a very fluid manor.

The below code creates the following output.

Untitled

Code Snippet
  1. // Create a document.
  2.             using (DocX document = DocX.Create("Test.docx"))
  3.             {
  4.                 // Add a hyperlink into the document.
  5.                 Hyperlink link = document.AddHyperlink("link", new Uri("http://www.google.com"));
  6.  
  7.                 // Add a Table into the document.
  8.                 Table table = document.AddTable(2, 2);
  9.                 table.Design = TableDesign.ColorfulGridAccent2;
  10.                 table.Alignment = Alignment.center;
  11.                 table.Rows[0].Cells[0].Paragraphs[0].Append("3");
  12.                 table.Rows[0].Cells[1].Paragraphs[0].Append("1");
  13.                 table.Rows[1].Cells[0].Paragraphs[0].Append("4");
  14.                 table.Rows[1].Cells[1].Paragraphs[0].Append("1");
  15.  
  16.                 // Add an image into the document.    
  17.                 Novacode.Image image = document.AddImage("Image.jpg");
  18.  
  19.                 // Create a picture (A custom view of an Image).
  20.                 Picture picture = image.CreatePicture();
  21.                 picture.Rotation = 10;
  22.                 picture.SetPictureShape(BasicShapes.cube);
  23.  
  24.                 // Insert a new Paragraph into the document.
  25.                 Paragraph title = document.InsertParagraph().Append("Test").FontSize(20).Font(new FontFamily("Comic Sans MS"));
  26.                 title.Alignment = Alignment.center;
  27.  
  28.                 // Insert a new Paragraph into the document.
  29.                 Paragraph p1 = document.InsertParagraph();
  30.  
  31.                 // Append content to the Paragraph
  32.                 p1.AppendLine("This line contains a ").Append("bold").Bold().Append(" word.");
  33.                 p1.AppendLine("Here is a cool ").AppendHyperlink(link).Append(".");
  34.                 p1.AppendLine();
  35.                 p1.AppendLine("Check out this picture ").AppendPicture(picture).Append(" its funky don't you think?");
  36.                 p1.AppendLine();
  37.                 p1.AppendLine("Can you check this Table of figures for me?");
  38.                 p1.AppendLine();
  39.                 
  40.                 // Insert the Table after Paragraph 1.
  41.                 p1.InsertTableAfterSelf(table);
  42.  
  43.                 // Insert a new Paragraph into the document.
  44.                 Paragraph p2 = document.InsertParagraph();
  45.  
  46.                 // Append content to the Paragraph.
  47.                 p2.AppendLine("Is it correct?");
  48.  
  49.                 // Save this document.
  50.                 document.Save();
  51.             }

If you would like to request a new feature, report a bug or just say hi, send me an email at coffey.cathal@gmail.com

Happy coding,
Cathal

Future

As always, I offer this code to you for free. I am however a student and if you would like to help me pay of some of my student debt , you can make a donation to DocX via paypal.

Wednesday, June 9, 2010

DocX version 1.0.0.9

The summer is finally here and so is DocX version 1.0.0.9. I would like to say sorry once again for the long wait but I simply couldn’t allow DocX to effect my final year college exams.

I received lots of feature requests over the past few months. I intend to implement as many of these features as possible over the next few releases. I have decided to make many small releases instead of one large release.

So what's new in this release?

1) Hyperlinks

DocX now supports hyperlinks.

The Document class now contains AddHyperlink(string, Uri)
The Paragraph class now contains AppendHyperlink(Hyperlink);

Example

Code Snippet
  1. // Create a document.
  2. using (DocX document = DocX.Create(@"Test.docx"))
  3. {
  4.     // Add a hyperlink to this document.
  5.     Hyperlink h = document.AddHyperlink
  6.     ("Google", new Uri("http://www.google.com"));
  7.  
  8.     // Add a new Paragraph to this document.
  9.     Paragraph p = document.InsertParagraph();
  10.     p.Append("My favourite search engine is ");
  11.     p.AppendHyperlink(h);
  12.     p.Append(", I think it's great.");
  13.  
  14.     // Save all changes made to this document.
  15.     document.Save();
  16. }

Output

clip_image002[4]

2) Content Direction

The Paragraph class now contains a property called Direction which can be either LeftToRight or RightToLeft. This property has both a getter and setter function.

To accommodate Paragraph Direction

  1. The Document class now contains SetDirection(Direction)
  2. The Table class now contains SetDirection(Direction)
  3. The Row class now contains SetDirection(Direction)
  4. The Cell class now contains SetDirection(Direction)

Where Direction is an enum with the choices LeftToRight and RightToLeft.

Example

Code Snippet
  1. // Create a new document.
  2. using (DocX document = DocX.Create("Test.docx"))
  3. {
  4.     // Create a new Paragraph with the text "Hello World".
  5.     Paragraph p = document.InsertParagraph("Hello World.");
  6.  
  7.     // Make this Paragraph flow right to left. Default is left to right.
  8.     p.Direction = Direction.RightToLeft;
  9.  
  10.     // Save all changes made to this document.
  11.     document.Save();
  12. }

Output

clip_image002[6]

3) Indentation

The Paragraph class now contains four properties for setting Indentation.

  1. IndentationFirstLine(float) which indents only the first line of a paragraph.
  2. IndentationHanging(float) which indents all but the first line of a paragraph.
  3. IndentationBefore(float) which indents before content.
  4. IndentationAfter(float) which indents after content.

Example

Code Snippet
  1. // Create a new document.
  2. using (DocX document = DocX.Create("Test.docx"))
  3. {
  4.     // Create a new Paragraph.
  5.     Paragraph p = document.InsertParagraph("Line 1\nLine 2\nLine 3");
  6.  
  7.     // Indent only the first line of the Paragraph.
  8.     p.IndentationFirstLine = 1.0f;
  9.  
  10.     // Save all changes made to this document.
  11.     document.Save();
  12. }

Output

clip_image002[8]

4) Pictures

The Image class now contains a CreatePicture() function and the Paragraph class contains a AppendPicture(Picture) function. The below example should explain how these updates enable easier Paragraph building.

Example

Code Snippet
  1. using (DocX document = DocX.Create("Test.docx"))
  2. {
  3.     // Add an image to the document.
  4.     Image i = document.AddImage(@"Image.jpg");
  5.  
  6.     // Create a picture i.e. (A custom view of an image)
  7.     Picture p = i.CreatePicture();
  8.     p.FlipHorizontal = true;
  9.     p.Rotation = 10;
  10.  
  11.     // Create a new Paragraph.
  12.     Paragraph par = document.InsertParagraph();
  13.  
  14.     // Append content to the Paragraph.
  15.     par.Append("Here is a cool picture")
  16.        .AppendPicture(p)
  17.        .Append(" don't you think so?");
  18.  
  19.     // Save all changes made to this document.
  20.     document.Save();
  21. }

Output

clip_image002[10]

Future

As always, I offer this code to you for free. I am however a student and if you would like to help me pay of some of my student debt , you can make a donation to DocX via paypal.