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

Friday, May 28, 2010

DocX and Tables

Create and inserting Tables into documents is easy with DocX.

Simple Table
  1. // Create a document.
  2. using (DocX document = DocX.Create(@"Test.docx"))
  3. {
  4. // Add a Table to this document.
  5. Table t = document.AddTable(2, 3);
  6. // Specify some properties for this Table.
  7. t.Alignment = Alignment.center;
  8. t.Design = TableDesign.MediumGrid1Accent2;
  9. // Add content to this Table.
  10. t.Rows[0].Cells[0].Paragraphs.First().Append("A");
  11. t.Rows[0].Cells[1].Paragraphs.First().Append("B");
  12. t.Rows[0].Cells[2].Paragraphs.First().Append("C");
  13. t.Rows[1].Cells[0].Paragraphs.First().Append("D");
  14. t.Rows[1].Cells[1].Paragraphs.First().Append("E");
  15. t.Rows[1].Cells[2].Paragraphs.First().Append("F");
  16. // Insert the Table into the document.
  17. document.InsertTable(t);
  18. document.Save();
  19. }// Release this document from memory.

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

Untitled

Paragraphs inside Table Cells can of course contain content such as Images, Hyperlinks and custom text styles as in the below example.

Advance Table
  1. // Create a document.
  2. using (DocX document = DocX.Create(@"Test.docx"))
  3. {
  4. // Add a Table to this document.
  5. Table table = document.AddTable(2, 3);
  6. // Add a Hyperlink into this document.
  7. Hyperlink h = document.AddHyperlink("Google", new Uri("http://www.google.com"));
  8. // Add an Image into this document.
  9. Novacode.Image i = document.AddImage(@"Logo.png");
  10. // Create a Picture (Custom View) of this Image.
  11. Picture p = i.CreatePicture();
  12. p.Rotation = 10;
  13. // Specify some properties for this Table.
  14. table.Alignment = Alignment.center;
  15. table.Design = TableDesign.LightShadingAccent2;
  16. // Insert the Table into the document.
  17. Table t1 = document.InsertTable(table);
  18. // Add content to this Table.
  19. t1.Rows[0].Cells[0].Paragraphs.First().AppendHyperlink(h).Append(" is my favourite search engine.");
  20. t1.Rows[0].Cells[1].Paragraphs.First().Append("This text is bold.").Bold();
  21. t1.Rows[0].Cells[2].Paragraphs.First().Append("Underlined").UnderlineStyle(UnderlineStyle.singleLine);
  22. t1.Rows[1].Cells[0].Paragraphs.First().Append("Green").Color(Color.Green);
  23. t1.Rows[1].Cells[1].Paragraphs.First().Append("Right to Left").Direction = Direction.RightToLeft;
  24. t1.Rows[1].Cells[2].Paragraphs.First().AppendPicture(p);
  25. document.Save();
  26. }// Release this document from memory.

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

Untitled2

Happy coding,
Cathal

Thursday, December 10, 2009

Is DocX dead?

DocX is not dead. I have just returned to college to finish the fourth and final year of my (computer science and software engineering degree). At the moment because of lectures, assignments, and my final year project, I have very little time to contribute to DocX. I am still answering questions that people email me, but I cannot release a new version of DocX until my exams are finished in June. I have received a lot of emails lately requesting new features for DocX and I am maintaining a priority list of these, I will work off this list in June.

In case you are interested, below is some information about my final year project.

Project title: Real time, naked hand tracking with minimal calibration.
Overview: My project aims to answer the following question. Can a users hands be reliably tracked in real time from a video sequence without using markers, gloves or electronic devices?

Hands

It is now December and I have been working on this problem since September, I have had a lot of success in these 4 short months.

untitled22

At this point in time I am building example applications to demonstrate my projects use. I am easily able to extract two very useful pieces of information, the distance between my hands and the angle.

untitled222

Here is a video of what I have so far. The change in distance d and angle a between my hands controls the zoom and rotation of the teapot.


Let me know what you think,
Cathal

Saturday, October 31, 2009

Converting .docx into (.doc, .pdf, .html)

Introduction

A DocX user asked me during the week when was I going to support converting Word 2007 documents (.docx) into other useful forms such as  (.doc, .pdf, .html). I would love to add this functionality to DocX, however there is a problem.

The Problem

The only easy way to do this conversion, is to use Microsoft’s Office interop libraries. For anyone who doesn't know what Microsoft’s Office interop libraries are, I envy you.

The Microsoft Office interop libraries are available in the Add Reference dialog.

Untitled 

The Code

Once you have added a reference to Microsoft.Office.Interop.Word you can use the below project to convert a Word 2007 .docx into .doc, .pdf, and .html.

Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Word = Microsoft.Office.Interop.Word;
  6. using Microsoft.Office.Interop.Word;
  7.  
  8. namespace ConsoleApplication1
  9. {
  10.     class Program
  11.     {
  12.         static void Main(string[] args)
  13.         {
  14.             // Convert Input.docx into Output.doc
  15.             Convert(@"C:\users\cathal\Desktop\Input.docx", @"c:\users\cathal\Desktop\Output.doc", WdSaveFormat.wdFormatDocument);
  16.  
  17.             /*
  18.              * Convert Input.docx into Output.pdf
  19.              * Please note: You must have the Microsoft Office 2007 Add-in: Microsoft Save as PDF or XPS installed
  20.              * http://www.microsoft.com/downloads/details.aspx?FamilyId=4D951911-3E7E-4AE6-B059-A2E79ED87041&displaylang=en
  21.              */
  22.             Convert(@"c:\users\cathal\Desktop\Input.docx", @"c:\users\cathal\Desktop\Output.pdf", WdSaveFormat.wdFormatPDF);
  23.  
  24.             // Convert Input.docx into Output.html
  25.             Convert(@"c:\users\cathal\Desktop\Input.docx", @"c:\users\cathal\Desktop\Output.html", WdSaveFormat.wdFormatHTML);
  26.         }
  27.  
  28.         // Convert a Word 2008 .docx to Word 2003 .doc
  29.         public static void Convert(string input, string output, WdSaveFormat format)
  30.         {
  31.             // Create an instance of Word.exe
  32.             Word._Application oWord = new Word.Application();
  33.  
  34.             // Make this instance of word invisible (Can still see it in the taskmgr).
  35.             oWord.Visible = false;
  36.  
  37.             // Interop requires objects.
  38.             object oMissing = System.Reflection.Missing.Value;
  39.             object isVisible = true;
  40.             object readOnly = false;
  41.             object oInput = input;
  42.             object oOutput = output;
  43.             object oFormat = format;
  44.  
  45.             // Load a document into our instance of word.exe
  46.             Word._Document oDoc = oWord.Documents.Open(ref oInput, ref oMissing, ref readOnly, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref isVisible, ref oMissing, ref oMissing, ref oMissing, ref oMissing);
  47.  
  48.             // Make this document the active document.
  49.             oDoc.Activate();
  50.  
  51.             // Save this document in Word 2003 format.
  52.             oDoc.SaveAs(ref oOutput, ref oFormat, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing);
  53.             
  54.             // Always close Word.exe.
  55.             oWord.Quit(ref oMissing, ref oMissing, ref oMissing);
  56.         }
  57.     }
  58. }

The result

 

image
Input.docx

 

image

image

image

Output.doc

Output.pdf

Output.html

Please note

This code will only execute on a machine that has Microsoft’s Office installed on it. The Microsoft’s Office interop libraries actually execute a “hidden” instance of the Office. If you run the above code and then take a look at taskmgr you will see the following.

image

If you want to convert to .pdf, you must also have the Microsoft Office 2007 Add-in: Microsoft Save as PDF or XPS installed.

It is for this reason that I have not included convert functionality into my DocX library. I do not want DocX to have a dependency on Word.exe.

The future

Is there no way to do conversions without having Word.exe installed on my machine. I didn’t say that, I said there is no easy way. This looks very promising, now if I could only find the time.

Donation?

As always, I offer this code to you for free. I am however a student and if you would like to say thank you, you can buy me lunch by sending a €5 euro donation via paypal.

Thursday, September 17, 2009

DocX codeplex page redesign

I have spent some time over the past few days redesigning http://docx.codeplex.com. I have decided to go with a minimalistic design, my girlfriend Cristina who created all of the art work for me, told me that I should not be afraid of white space. I think she's on to something.

The biggest addition to the new page design is a section aptly named “How do I learn more?”. It is my intention to upload a large series of video tutorials to this section, I have already uploaded the first two.

1. Getting started with DocX.
2. Paragraphs and text formatting.

If you have any requests, topics that you would like to see covered, please send them to coffey.cathal@gmail.com. I am definitely going to create a video about CustomProperties, and another about Images and Pictures. I would also welcome feedback about the new page design, both positive and negative.

Kind regards and happy coding,
Cathal

Friday, August 28, 2009

DocX v1.0.0.8 released

DocX version 1.0.0.8 is now available for download from here. So what's new in this version? Why should you download it?

The biggest addition to this version of DocX is a better method of building highly formatted Paragraphs. This new method is a fluent interface and it was proposed by one of DocX's users Morten Bjerre. So what is a fluent interface? This Wikipedia article explains fluent interfaces quite well.

Here is an example of how this new addition to DocX makes building highly formatted Paragraphs easier and more intuitive. Lets say that we want to create a document that looks like this.

Untitled
This can now be accomplished with the below code.

// Create a document.
using (DocX document = DocX.Create(@"Test.docx"))
{
// Insert a new Paragraphs.
Paragraph p = document.InsertParagraph();

p.Append(
"I am ").Append("bold").Bold()
.Append(
" and I am ")
.Append(
"italic").Italic().Append(".")
.AppendLine(
"I am ")
.Append(
"Arial Black")
.Font(
new FontFamily("Arial Black"))
.Append(
" and I am not.")
.AppendLine(
"I am ")
.Append(
"BLUE").Color(Color.Blue)
.Append(
" and I am")
.Append(
"Red").Color(Color.Red).Append(".");

// Save this document.
document.Save();
}
// Release this document from memory.


This version of DocX also contains three new features that were added by a user
Joel Folkerts. Joel is the first user to post working and tested code for inclusion in DocX. These new features are listed below.
1. Row.Height property
2.
Cell.Width property
3. Row.MergeCells
Row.Height and Cell.Width are self explanatory but here is an example of using Row.MergeCells. Lets say we have the following Table.
UntitledWe can merge the cells {1-3} and the cells {6-8} on row 1 to get the following table.Untitled3This can now be accomplished in DocX with the following code.
// Load a document.
using (DocX document = DocX.Load(@"Test.docx"))
{
// Grab the first Table.
Table t = document.Tables[0];

// Grab the first Row of this Table.
Row r = t.Rows[1];

// Merge the cells 1-3 into one new cell.
r.MergeCells(1, 3);

// Merge the cells 4-6
r.MergeCells(4, 6);

// Save all changes made to this document.
document.Save();
}
// Release this document from memory.


I have also added a new feature that was requested by a user Mathetes. This new feature allows TextReplace() to take a Formatting object as an extra parameter and it then only returns text that matches both the input string and that format. Another new extra parameter for this function is a new Formatting object to be applied to the inserted text.
// Load a document.
using (DocX document = DocX.Load(@"Test.docx"))
{
// The formatting to match.
Formatting matchFormatting = new Formatting();
matchFormatting.Size = 10;
matchFormatting.Italic =
true;
matchFormatting.FontFamily =
new FontFamily("Times New Roman");

// The new formatting to apply.
Formatting newFormatting = new Formatting();
newFormatting.Size = 22;
newFormatting.UnderlineStyle =
UnderlineStyle.dotted;
newFormatting.Bold =
true;

// Iterate through the paragraphs
foreach (Paragraph p in document.Paragraphs)
{
p.ReplaceText
(
"wrong", "right", false,
RegexOptions.IgnoreCase,
newFormatting, matchFormatting,
MatchFormattingOptions.SubsetMatch
);
}

// Save all changes made to this document.
document.Save();
}
// Release this document from memory.
I want to take this opportunity to say a huge thank you to Morten Bjerre, Joel Folkerts and Mathetes. You have all enhanced DocX greatly with the features that you have added to this version.

If anyone out there reading this wants to suggest a new feature, please send it my way. I will try my best to include it in a future version for DocX.
happy coding,
Cathal

Friday, August 14, 2009

DocX v1.0.0.7 released

I have just uploaded DocX version 1.0.0.7 to docx.codeplex.com. This version comes with an extra optional download “Advance – Invoice Example.zip”.

“Advance – Invoice Example.zip” is a zipped Visual Studio 2008 solution that I created to demonstrate how far DocX has evolved since version 1.0.0.1. The first time that you run InvoiceExample.exe it will check for the existence of a document called “InvoiceTemplate.docx”, because this is the first execution this document will not exist, so it is created.

Figure 1.0 - InvoiceTemplate.docx created by first run of InvoiceExample.exe

It is important to note that everything you see in the above screenshot was created by DocX. If you now run InvoiceExample.exe again the document “InvoiceTemplate.docx” is found and it is now used to create an invoice for a factitious company called “The Happy Builder”.

Figure 1.1 - Invoice_The_Happy_Builder.docx created by second run of InvoiceExample.exe

As you can see DocX has loaded the document “InvoiceTemplate.docx” into memory and customized it. This was done by setting custom property values, inserting an image, creating a picture from this image, and replacing a Table with a new Table that contains data from a data source.

This example is intended for an experienced user of DocX. A first time user may find this solution overwhelming. Over the next few days, I am going to create a video tutorial called "Getting started with DocX". This video will be targeted at the first time user of DocX.

I hope that from this example you can see how quickly Docx is growing and also how useful it is becoming. As always if you would like to report a bug, request a feature or even just say hi, please email me at coffey.cathal@gmail.com.

happy coding,
Cathal

DocX is completely free, but if you have found it useful and you would like to make a donation you can do so via paypal.

Tuesday, August 4, 2009

DocX version 1.0.0.6 released

Hi again, sorry it has been so long since my last post. My progress in the physical world has slowed my progress in the digital.

This newest version of DocX brings many bug fixes and also two new features. Firstly, I would like to thank the following people for taking the time to email me with bugs and feature requests. Without your interest and feedback, DocX would not progress.

Many thanks to: John Marsh, Francesco, Johan Laagland, Gaspar, Brian (chicken), Jianbang, Christopher W. Steelman, Peter Thompson, Brian Minert.

New features

1) InsertDocProperty(CustomProperty cp)

CustomProperties are displayed in a document using fields of type DocProperty. Until this version, DocX was capable of adding a CustomProperty to a document, but it was not capable of displaying these CustomProperties. As of DocX version 1.0.0.6, this is now possible, below is an example.

// Load a document
using (DocX document = DocX.Create(@"Test.docx"))
{
// Create a custom property.
CustomProperty name = new CustomProperty("name", "Cathal Coffey");

// Add this custom property to this document.
document.AddCustomProperty(name);

// Insert a new paragraph.
Paragraph p = document.InsertParagraph("Author: ", false);

// Insert a field of type document property to display the custom property name
p.InsertDocProperty(name);

// Save all changes made to this document.
document.Save();
}// Release this document from memory.
The above code example will create the following document. Please note that the text 'Cathal Coffey'
is being displayed by a field, this field's value is controlled by the CustomProperty 'name'.

2) FindAll(string str)
This version of DocX allows you to search a document for a string. The function
FindAll(string str) returns a list containing all of the start indexes of the found string.
Below is an example of this new function.
// Load a document
using (DocX document = DocX.Load(@"Test.docx"))
{
// Loop through the paragraphs in this document.
foreach (Paragraph p in document.Paragraphs)
{
// Find all instances of 'go' in this paragraph.
List<int> gos = document.FindAll("go");

/*
* Insert 'don't' in front of every instance of 'go' in this document to produce * 'don't go'. An important trick here is to do the inserting in reverse document * order. If you inserted in document order, every insert would shift the index * of the remaining matches.
*/
gos.Reverse();
foreach (int index in gos)
{
p.InsertText(index, "don't ", true);
}
}

// Save all changes made to this document.
document.Save();
}// Release this document from memory.
If the above code is run on this document (Drawing in red is to illustrate the index's of each instance of 'go').

Then the following document is produced.

As you can see, 'don't' was inserted at the original index of each instance of 'go'.

DocX is completely free, but if you have found it useful and you would like to make a donation you can do so via paypal.

As always, please contact me if you find any bugs, have any feature requests or just want to provide feedback.

happy coding,
Cathal