这个类PackageHelper ,是微软在发布OpenXML SDK之前给出的操作OpenXml的例子里的一个类,这个是操作word文档的那个,基本没有做什么修改,如果要操作Word文档的话,这个类基本是可以直接用的。
public class PackageHelper : IDisposable
{
#region 私有变量
private MemoryStream m_packageData;
private Package m_package;
#endregion
#region 构造函数
/// <summary>
/// 用给定数据创建一个Package对象的实例
/// </summary>
/// <param name="data">用来初始化package的比特数组</param>
public PackageHelper(byte[] data)
{
m_packageData = new MemoryStream();
m_packageData.Write(data, 0, data.Length);
// 打开 package
m_package =
Package.Open(m_packageData,
FileMode.Open,
FileAccess.ReadWrite); // 注意,这里要有写权限
//或者直接打开一个文件
//m_package = Package.Open("filename",FileMode.Open,FileAccess.ReadWrite)
}
#endregion
/// <summary>
/// 清理资源
/// </summary>
public void Dispose()
{
m_package.Close();
m_packageData.Dispose();
}
#region Package 管理方法
/// <summary>
/// Creates a relationship from one package part to another.
/// </summary>
/// <param name="sourceUri">The uri of the source part.</param>
/// <param name="targetUri">The relative path representing the location of the target part based on the source part.</param>
/// <param name="relationshipType">The type of relationship to create.</param>
/// <returns>The ID of the new relationship.</returns>
public string CreateInternalRelationship(Uri sourceUri, Uri targetUri, string relationshipType)
{
// open the source part
PackagePart sourcePart = m_package.GetPart(sourceUri);
// create the relationship
PackageRelationship relationship =
sourcePart.CreateRelationship(
PackUriHelper.GetRelativeUri(sourceUri, targetUri),
TargetMode.Internal, relationshipType);
// return the new rel id
return relationship.Id;
}
/// <summary>
///保存package到一个文件。
/// </summary>
/// <param name="filename">要保存的文件</param>
public void Save(string filename)
{
// flush and data in the package buffers to the stream
m_package.Flush();
m_package.Close();
// write the stream to the output file
using (FileStream outputStream = File.Create(filename))
m_packageData.WriteTo(outputStream);
// close the stream
m_packageData.Close();
}
#endregion
#region Part Management Methods
/// <summary>
/// 检查指定的Part是否存在
/// </summary>
/// <param name="partUri">The uri of the part to find.</param>
/// <returns>A boolean value specifying if the part exists.</returns>
public bool PartExists(Uri partUri)
{
// get the part if it exists
return m_package.PartExists(partUri);
}
/// <summary>
/// Creates a new part containing the data provided.
/// </summary>
/// <param name="partUri">The uri of the part to create.</param>
/// <param name="contentType">The content type for the new part.</param>
/// <param name="data">The data to initially load into the new part.</param>
/// <returns></returns>
public PackagePart CreateNewPart(Uri partUri, string contentType, byte[] data)
{
if (PartExists(partUri))
return m_package.GetPart(partUri);
// create the part
PackagePart newPart =
m_package.CreatePart(partUri, contentType, CompressionOption.Normal);
// write the data into the part
using (Stream partStream =
newPart.GetStream(FileMode.Create, FileAccess.Write))
{
partStream.Write(data, 0, data.Length);
}
// return the new package part
return newPart;
}
public PackagePart CreateNewPart(Uri partUri, string contentType, string fileName)
{
if (PartExists(partUri))
return m_package.GetPart(partUri);
PackagePart newPart =
m_package.CreatePart(partUri, contentType,CompressionOption.Normal);
if (File.Exists(fileName))
{
FileStream ifs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
using (Stream partStream =
newPart.GetStream(FileMode.Create, FileAccess.Write))
{
byte[] byteTmp = new byte[1024];
int count = 0;
while ((count = ifs.Read(byteTmp, 0, 1024)) > 0)
{
partStream.Write(byteTmp, 0, count);
}
}
}
return newPart;
}
/// <summary>
/// Opens the part and loads the XML into an XPathDocument.
/// </summary>
/// <param name="partUri">The uri of the part to open.</param>
/// <returns>Read only XPathDocument containing the xml from the part.</returns>
public XPathDocument GetReadOnlyPart(Uri partUri)
{
// retrieve the part
PackagePart readOnlyPart = m_package.GetPart(partUri);
// load the part into a XPathDocument
using (Stream partStream = readOnlyPart.GetStream(FileMode.Open, FileAccess.Read))
return new XPathDocument(partStream);
}
/// <summary>
/// Opens the part and loads the XML into an XmlDocument.
/// </summary>
/// <param name="partUri">The uri of the part to open.</param>
/// <returns>XmlDocument containing the xml from the part.</returns>
public XmlDocument GetWritablePart(Uri partUri)
{
// get the part
PackagePart writablePart = m_package.GetPart(partUri);
// load the part into a XmlDocument
XmlDocument partXml = new XmlDocument();
using (Stream partStream = writablePart.GetStream(FileMode.Open, FileAccess.Read))
partXml.Load(partStream);
// return the document
return partXml;
}
public XmlReader GetWritablePartAsReader(Uri partUri)
{
// get the part
PackagePart writablePart = m_package.GetPart(partUri);
// load the part into a XmlReader
return XmlReader.Create(writablePart.GetStream());
}
public Stream GetWritablePartAsStream(Uri partUri)
{
// get the part
PackagePart writablePart = m_package.GetPart(partUri);
// load the part into a stream
return writablePart.GetStream();
}
/// <summary>
/// Replaces all content in the part with the XML in the XmlDocument.
/// </summary>
/// <param name="partUri">The uri of the part to replace.</param>
/// <param name="partXml">XmlDocument containing the xml to place into the part.</param>
public void SavePart(Uri partUri, XmlDocument partXml)
{
// get the part
PackagePart writablePart = m_package.GetPart(partUri);
// load the part into a XmlDocument
using (Stream partStream =
writablePart.GetStream(FileMode.Open, FileAccess.Write))
{
partStream.SetLength(0);
partXml.Save(partStream);
}
}
#endregion
#region Private Methods
/// <summary>
/// Creates a relative uri based on two other relative Uri's.
/// </summary>
/// <param name="sourceUri">The uri navigation is starting from.</param>
/// <param name="targetUri">The uri of the resource to access.</param>
/// <returns>A relative Uri defining the path from the source Uri to the target Uri.</returns>
private Uri BuildRelativeUri(Uri sourceUri, Uri targetUri)
{
string[] sourceSegments = sourceUri.OriginalString.Split('/');
string[] targetSegments = targetUri.OriginalString.Split('/');
// find the number of shared segments
int sharedSegments = 0;
int maxSegments = Math.Min(sourceSegments.Length, targetSegments.Length) - 1;
for (; sharedSegments != maxSegments; sharedSegments++)
if (sourceSegments[sharedSegments] != targetSegments[sharedSegments])
break;
// build the relative uri
StringBuilder relativeUri = new StringBuilder();
for (int i = 0; i != sourceSegments.Length - 1 - sharedSegments; i++)
relativeUri.Append("../");
for (int i = sharedSegments; i != targetSegments.Length - 1; i++)
{
relativeUri.Append(targetSegments[i]);
relativeUri.Append("/");
}
relativeUri.Append(targetSegments[targetSegments.Length - 1]);
// return the new relative Uri
return new Uri(relativeUri.ToString(), UriKind.Relative);
}
#endregion
}