Click here to Skip to main content
15,891,529 members
Articles / Productivity Apps and Services / Microsoft Office

Printing Documents from C# using OpenOffice Writer

Rate me:
Please Sign up or sign in to vote.
4.00/5 (19 votes)
7 May 2008BSD2 min read 117.3K   6.8K   53  
Simple printing solution based on OpenOffice suite
using System;
using System.IO;
using System.Xml;
using System.Text;
using System.Collections;
using System.Diagnostics;

using ICSharpCode.SharpZipLib;
using ICSharpCode.SharpZipLib.Zip;

	// Class for printing of odt files in OpenOffice
public class Odt
{
	public static string OoExe;			// path to soffice.exe
	public static string SaveDir;		// default directory, where documents are saved before printing

	private string templateFile;
	private XmlDocument doc;
	OdtDocFields inputs;

	public Odt(string odtFile)
	{
		Load(odtFile);
	}

	#region OoExe

	static void SetOoExe(string path)
	{
		if(OoExe == null && File.Exists(path))
		{
			OoExe = path;
		}
	}

	static Odt()
	{
		SetOoExe(@"C:\Program Files\OpenOffice.org 2.3\program\soffice.exe");
		SetOoExe(@"C:\Program Files\OpenOffice.org 2.2\program\soffice.exe");
		SetOoExe(@"C:\Program Files\OpenOffice.org 2.0\program\soffice.exe");
		SetOoExe(@"C:\Program Files\OpenOffice.org 3.2\program\soffice.exe");
		SetOoExe(@"C:\Program Files\OpenOffice.org 3.1\program\soffice.exe");
		SetOoExe(@"C:\Program Files\OpenOffice.org 3.0\program\soffice.exe");
		SetOoExe(@"C:\Program Files\OpenOffice.org 2.6\program\soffice.exe");
		SetOoExe(@"C:\Program Files\OpenOffice.org 2.5\program\soffice.exe");
		SetOoExe(@"C:\Program Files\OpenOffice.org 2.4\program\soffice.exe");

		SaveDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
	}

	#endregion

	#region Collections

	// Collection used to access document input fields
	public class OdtDocFields
	{
		private Odt odt;
		private Hashtable ht;
		private string[] fieldNames;

		public OdtDocFields(Odt odt)
		{
			this.odt = odt;
			this.ht = new Hashtable();
		}

		public int Count
		{
			get
			{
				return ht.Count;
			}
		}

		public string this[string fieldName]
		{
			get
			{
				return ((XmlNode)(ht[fieldName])).InnerText;
			}
			set
			{
				((XmlNode)(ht[fieldName])).InnerText = (string) value;
			}
		}

		public void AddNode(XmlNode node)
		{
			string desc = node.Attributes["text:description"].Value;
			ht[desc] = node;
		}

		public string[] FieldNames
		{
			get
			{
				if(fieldNames == null)
				{
					fieldNames = new string[ht.Count];
					ht.Keys.CopyTo(fieldNames, 0);
				}
				return fieldNames;
			}
		}
	}

	#endregion

	public OdtDocFields Inputs
	{
		get
		{
			return inputs;
		}
	}

	public void Load(string odtTemplateFile)
	{
		this.templateFile = odtTemplateFile;

		// Read content.xml
		using(ZipInputStream zis = new ZipInputStream(File.OpenRead(templateFile)))
		{
			ZipEntry ze;
			while((ze = zis.GetNextEntry()) != null)
			{
				if(ze.Name == "content.xml")
				{
					StreamReader sr = new StreamReader(zis, Encoding.UTF8);
					string text = sr.ReadToEnd();
					doc = new XmlDocument();
					doc.LoadXml(text);
					break;
				}
			}
		}

		// Add all input fields in collection
		inputs = new OdtDocFields(this);
		PopulateInputs(doc.DocumentElement);
	}

	private void PopulateInputs(XmlNode node)
	{
		if(node.Name == "text:text-input")
		{
			inputs.AddNode(node);
		}
		foreach(XmlNode child in node.ChildNodes)
		{
			PopulateInputs(child);
		}
	}

	public void Save(string fileName)
	{
		int count;
		byte[] buf = new byte[4096];
		DateTime now = DateTime.Now;

		using(ZipInputStream zis = new ZipInputStream(File.OpenRead(templateFile)))
		{
			using(ZipOutputStream zos = new ZipOutputStream(File.OpenWrite(fileName)))
			{
				ZipEntry ze;
				while((ze = zis.GetNextEntry()) != null)
				{
					ZipEntry entry = new ZipEntry(ze.Name);
					entry.DateTime = now;
					zos.PutNextEntry(entry);

					if(ze.Name == "content.xml")
					{
						string text = doc.OuterXml;
						byte[] textBytes = Encoding.UTF8.GetBytes(text);
						zos.Write(textBytes, 0, textBytes.Length);
					}
					else
					{
						while((count = zis.Read(buf, 0, buf.Length)) > 0)
						{
							zos.Write(buf, 0, count);
						}
					}
				}

				zos.Finish();
			}
		}
	}

	private Process RunOo(string args)
	{
		if(OoExe == null)
		{
			throw new Exception("OpenOffice not found - either not installed or at unknown path");
		}

		Process p = new Process();
		p.StartInfo.FileName = OoExe;
		p.StartInfo.WorkingDirectory = Path.GetDirectoryName(OoExe);
		p.StartInfo.Arguments = "-writer " + args;
		p.Start();
		return p;
	}

	private Process RunOo(string args, string fileName)
	{
		return RunOo(args + " \"" + fileName + "\"");
	}

	private string GetTmpFile()
	{
		string fileName;
		int no = 0;
			
		// Find unique name in the SaveDir
		do
		{
			fileName = Path.Combine(SaveDir, String.Format("{0}_{1:yyyy_MM_dd_HH_mm}{2}.odt",
				Path.GetFileNameWithoutExtension(templateFile),
				DateTime.Now,
				no == 0 ? "" : "(" + (no++) + ")"));
		}
		while(File.Exists(fileName));
		return fileName;
	}

	public void Print(string fileToSave)
	{
		Save(fileToSave);
		RunOo("-p", fileToSave);
	}

	public void Print()
	{
		Print(GetTmpFile());
	}

	public void OpenInOo(string fileToSave)
	{
		Save(fileToSave);
		RunOo("", fileToSave);
	}

	public void OpenInOo()
	{
		OpenInOo(GetTmpFile());
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The BSD License


Written By
Software Developer ODP-software spol. s r. o.
Czech Republic Czech Republic
Started programming on Z80. Later on PC i started playing with Linux and joined the DotGNU project. Here i implemented debugger and fixed a few easy bugs. I have also started project PortableStudio which will be DotGNU's IDE. At work i am developing ticket system for Czech Railways and systems for on board sales for Czech Airways.

Comments and Discussions