Thursday, March 19, 2009
On Further Review…
Wednesday, March 18, 2009
Reading a Office 2007 docx file using C# and SharpZipLib
I found myself needing to read a office 2007 docx file to get the xml of the document., so I went and got the ECMA spec for OfficeOpenXML. That is a heavy 1500 page heavy read :-). So I decided to keep it handy and just write some code to see how bad it would be. So far it has not been as bad as I thought it would be so I thought I would post some code on it. It has been a while since I have posted anything, so here goes.
The docx file is actually just a zip archive of a bunch of files. The trick here is to read the zip and pull out the content. I decided I wanted to load the data to a class hierarchy so I could do some Linq to objects work with it.
So I will start this with some simple code. First the DocumentPart.cs class holds the document content and some information from it’s zip file. The document content is stored as a linq to XML XDocument..
1 using System;
2 using System.Xml.Linq;
3 4 namespace OfficeOpenXML.Package
5 {6 /// <summary>
7 /// A document part in the OfficeOpenXML Package
8 /// </summary>
9 public class DocumentPart
10 {11 public string Name {get; set; }
12 public string Comment { get; set; }
13 public long CompressedSize { get; set; }
14 public DateTime EntryDate { get; set; }
15 public long Size { get; set; }
16 public XDocument Content { get; set; }
17 } 18 }It is pretty basic so far (love those automatic properties).
Now how do you read the zip file? I use the SharpZipLib to read the zip file and then store each member of the zip archive into a dictionary of DocumentPart with the filename as the Dictionary key.
1 using System;
2 using System.Collections.Generic;
3 using System.IO;
4 using System.Text;
5 using System.Xml.Linq;
6 using ICSharpCode.SharpZipLib.Zip;
7 8 namespace OfficeOpenXML.Package
9 {10 public class Parts
11 {12 public Dictionary<string, DocumentPart> DocumentParts { get; set; }
13 public string FilePath { get; set; }
14 15 public void OpenPackage(string filePath)
16 {17 ZipEntry Entry;
18 XDocument contents;
19 StringBuilder XMLDocument;
20 byte[] Buffer = new Byte[8192];
21 int bytesRead;
22 23 using (ZipInputStream Package =
24 new ZipInputStream(new StreamReader(filePath).BaseStream))
25 {26 while ((Entry = Package.GetNextEntry()) != null)
27 {28 XMLDocument = new StringBuilder();
29 while ((bytesRead = Package.Read(Buffer, 0, Buffer.Length)) != 0)
30 { 31 XMLDocument.Append(32 ASCIIEncoding.ASCII.GetString(Buffer, 0, bytesRead));
33 }34 contents = XDocument.Parse(XMLDocument.ToString());
35 DocumentParts.Add(Entry.Name, new DocumentPart()
36 { Name=Entry.Name, Size=Entry.Size, 37 Comment=Entry.Comment, 38 CompressedSize=Entry.CompressedSize, 39 EntryDate=Entry.DateTime, Content=contents }); 40 } 41 } 42 } 43 44 /// <summary>
45 /// Construct the class
46 /// </summary>
47 /// <param name="filePath">The office Open XML document</param>
48 public Parts(string filePath)
49 { 50 FilePath = FilePath;51 DocumentParts = new Dictionary<string, DocumentPart>();
52 } 53 } 54 }I use the using statement (on line 23) to handle the opening the docx file and then process the zip archive using the GetNextEntry. The inner while loop (at line 28) reads the content of the entry into a string. Finally while the DocumentParts.Add() adds the document dictionary.
A simple NUnit test (not exhaustive by any means) is:
1 using NUnit.Framework;
2 3 namespace OfficeOpenXML.UnitTests.Package
4 {5 [TestFixture]
6 public class PartTests
7 {8 [Test]
9 public void OpenPackageTest()
10 {11 OfficeOpenXML.Package.Parts p = new OfficeOpenXML.Package.Parts();
12 p.OpenPackage("../../TestData/AbilitiesandConditions.docx");
13 Assert.IsTrue(p.DocumentParts.ContainsKey("[Content_Types].xml"), "No Content_Types?");
14 } 15 } 16 }In my next post I will show how to use the information from the [Content_Types].xml entry and the docsprops/app.xml and docprops/core.xml files to create an object that has information about the document being read (using some Linq to XML to populate the Class).
Darrel
Wednesday, March 11, 2009
Red, Green, Re-factor
I find my self getting more and more into the test driven development paradigm. I am working on some fairly heavy OO code with a great requirement specification (it is actually and ISO standard).
The application is growing pretty much via the unit tests. Write the test, then make sure the code fits. It is amazing how many times I am not sure how a piece of code is going to work so I just put together the unit test to fit the standard and then code the class. I can then re-factor as needed.
I am using the speech API’s to drive the interface so the speech api simply outputs a string of text that I can use to execute the program commands. I wanted the program to be able to be both driven by speech commands and through the standard GUI approach. Since I am working on a compiler, interpreter I have simply added the speech grammar as another grammar in the compiler. .I will probably do the same to parse the command line options.
Makes for some interesting code :-).
Tuesday, March 10, 2009
Not posting much lately
I have been working on several projects. They are starting to come to completion and I hope to post some more on them at the beginning of April. I have also been busy with contracts and life in general, but I will get back to some posts in a few weeks.
Monday, October 13, 2008
Human Costs of a Bad Economy
I have been traveling around the country for the past 90 days through the Midwest, the east coast and the south and staying in a lot of hotels. Most recently my hotel in Daytona Beach.
Now my hotel is right on the ocean. In fact my balcony faces the ocean and the pool. All in all not a bad place that I got for $32.50 a night. Now Daytona Beach is a resort town. All most all of the business here comes from the tourists. With the state of the economy there are virtually no tourists around, the hotels and restaurants are getting almost no business. Ditto for the tourist shops. You can almost watch them close all up and down Atlantic Boulevard.
As a geek I make pretty good money. As a matter of fact I probably make more then any of the cooks, house keepers or shopkeepers around here. it is sad when you hear some have cut back on hours to less then 20 hours a week. I mean they already don't make that much and now they make half of that and most of them are not that well off.
You can only hope it gets better soon for all of us.
Friday, October 3, 2008
Sunny Florida
Well, I am the second elgant coder to be outside of the Boise, Id area. I have moved to Florida and am currently camped in a hotel on Ormond Beach.
Although I enjoyed my 10 years in Boise it was time to move on. After being riffed off from Micron I was pretty much at ends as to what was keeping me in Boise. I had originally moved there in 1997 to be around my mom. After she died in 2003 there was little keeping me in Boise except for momentum. I had no real reason to change. Micron's layoffs gave me a good reason to think about moving on.
I have always wanted to see a shuttle launch and wanted to be around a ocean again. So with those two criteria Florida was really the only choice. I spent two months driving across America seeing family I had not caught up with in years. In addition I spent some time just seeing the country. Something I have wanted to do for years. I traveled 9000 miles in 60 days and went from one end of the country to the other. A great trip for me and the cat (although I am not sure the cat would agree :-)). I will be posting some blog entries about the trip over the next few weeks.
For now I am planning on staying on Florida for a while. I will start looking for full time work next week. I am excited about the change and looking forward to some new challenges.
Saturday, July 12, 2008
The Tablet PC
I recently took a tumble (anyone who knows me will tell you I am clumsy) and hurt my right arm. Needless to say this is not good if you and a computer geek. Fortunately at the same time I was trading out my Dell 1720 for a new dell lattitude XT. So I am actually writing this blog entry. Literally! I am using the handwriting recognition features of the tablet PC.
So far I am very impressed. The tablet does a better job reading my handwriting they some of my friends do (hi joe!). It is interesting that it reads my writing better then my printing. For some reason all those years I actually thought my printing was easier to read then my writing. Guess I was wrong. I am pretty sure I actually can write faster than I can type. This as is kind of sad knowing ] have made my living writing computer programs for the last 30 years.
I will have to bring up my visual studio 2008 environment and see how easy it is to code this way. l should point out I am doing this all on Vista Ultimate. I did not like Tablet XP any where as much as Vista.