방법: Office Open XML 문서 수정
업데이트: November 2007
이 항목에서는 Office Open XML 문서를 열고, 수정하고, 저장하는 예제를 제공합니다.
Office Open XML에 대한 자세한 내용은 www.openxmldeveloper.org를 참조하십시오.
예제
이 예제에서는 문서의 첫 번째 단락 요소를 찾고 단락에서 텍스트를 검색한 다음 단락의 모든 텍스트 실행을 삭제합니다. 또한 대문자로 변환된 첫 번째 단락 텍스트로 구성된 새로운 텍스트 실행을 만들고 변경된 XML을 Open XML 패키지로 serialize한 후 닫습니다.
이 예제에서는 WindowsBase 어셈블리의 클래스를 사용하고 System.IO.Packaging 네임스페이스의 형식을 사용합니다.
public static class LocalExtensions
{
public static string StringConcatenate(this IEnumerable<string> source)
{
StringBuilder sb = new StringBuilder();
foreach (string s in source)
sb.Append(s);
return sb.ToString();
}
public static string StringConcatenate<T>(this IEnumerable<T> source,
Func<T, string> func)
{
StringBuilder sb = new StringBuilder();
foreach (T item in source)
sb.Append(func(item));
return sb.ToString();
}
public static string StringConcatenate(this IEnumerable<string> source, string separator)
{
StringBuilder sb = new StringBuilder();
foreach (string s in source)
sb.Append(s).Append(separator);
return sb.ToString();
}
public static string StringConcatenate<T>(this IEnumerable<T> source,
Func<T, string> func, string separator)
{
StringBuilder sb = new StringBuilder();
foreach (T item in source)
sb.Append(func(item)).Append(separator);
return sb.ToString();
}
}
class Program
{
public static string ParagraphText(XElement e)
{
XNamespace w = e.Name.Namespace;
return e
.Elements(w + "r")
.Elements(w + "t")
.StringConcatenate(element => (string)element);
}
static void Main(string[] args)
{
const string fileName = "SampleDoc.docx";
const string documentRelationshipType =
"https://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
const string stylesRelationshipType =
"https://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
const string wordmlNamespace =
"https://schemas.openxmlformats.org/wordprocessingml/2006/main";
XNamespace w = wordmlNamespace;
using (Package wdPackage = Package.Open(fileName, FileMode.Open, FileAccess.ReadWrite))
{
PackageRelationship docPackageRelationship =
wdPackage.GetRelationshipsByType(documentRelationshipType).FirstOrDefault();
if (docPackageRelationship != null)
{
Uri documentUri = PackUriHelper.ResolvePartUri(new Uri("/", UriKind.Relative),
docPackageRelationship.TargetUri);
PackagePart documentPart = wdPackage.GetPart(documentUri);
// Load the document XML in the part into an XDocument instance.
XDocument xDoc = XDocument.Load(XmlReader.Create(documentPart.GetStream()));
// Find the styles part. There will only be one.
PackageRelationship styleRelation =
documentPart.GetRelationshipsByType(stylesRelationshipType).FirstOrDefault();
PackagePart stylePart = null;
XDocument styleDoc = null;
if (styleRelation != null)
{
Uri styleUri = PackUriHelper.ResolvePartUri(documentUri, styleRelation.TargetUri);
stylePart = wdPackage.GetPart(styleUri);
// Load the style XML in the part into an XDocument instance.
styleDoc = XDocument.Load(XmlReader.Create(stylePart.GetStream()));
}
XElement paraNode = xDoc
.Root
.Element(w + "body")
.Descendants(w + "p")
.FirstOrDefault();
string paraText = ParagraphText(paraNode);
// remove all text runs
paraNode.Descendants(w + "r").Remove();
paraNode.Add(
new XElement(w + "r",
new XElement(w + "t", paraText.ToUpper())
)
);
// Save the XML into the package
using (XmlWriter xw =
XmlWriter.Create(documentPart.GetStream(FileMode.Create, FileAccess.Write)))
{
xDoc.Save(xw);
}
Console.WriteLine("New first paragraph: >{0}<", paraText.ToUpper());
}
}
}
}
Imports <xmlns:w="https://schemas.openxmlformats.org/wordprocessingml/2006/main">
Module Module1
<System.Runtime.CompilerServices.Extension()> _
Public Function StringConcatenate(ByVal source As IEnumerable(Of String)) As String
Dim sb As StringBuilder = New StringBuilder()
For Each s As String In source
sb.Append(s)
Next
Return sb.ToString()
End Function
<System.Runtime.CompilerServices.Extension()> _
Public Function StringConcatenate(Of T)(ByVal source As IEnumerable(Of T), _
ByVal func As Func(Of T, String)) As String
Dim sb As StringBuilder = New StringBuilder()
For Each item As T In source
sb.Append(func(item))
Next
Return sb.ToString()
End Function
<System.Runtime.CompilerServices.Extension()> _
Public Function StringConcatenate(Of T)(ByVal source As IEnumerable(Of T), _
ByVal separator As String) As String
Dim sb As StringBuilder = New StringBuilder()
For Each s As T In source
sb.Append(s).Append(separator)
Next
Return sb.ToString()
End Function
<System.Runtime.CompilerServices.Extension()> _
Public Function StringConcatenate(Of T)(ByVal source As IEnumerable(Of T), _
ByVal func As Func(Of T, String), ByVal separator As String) As String
Dim sb As StringBuilder = New StringBuilder()
For Each item As T In source
sb.Append(func(item)).Append(separator)
Next
Return sb.ToString()
End Function
Public Function ParagraphText(ByVal e As XElement) As String
Dim w As XNamespace = e.Name.Namespace
Return (e.<w:r>.<w:t>).StringConcatenate(Function(element) CStr(element))
End Function
' Following function is required because VB does not support short circuit evaluation
Private Function GetStyleOfParagraph(ByVal styleNode As XElement, _
ByVal defaultStyle As String) As String
If (styleNode Is Nothing) Then
Return defaultStyle
Else
Return styleNode.@w:val
End If
End Function
Sub Main()
Dim fileName = "SampleDoc.docx"
Dim documentRelationshipType = _
"https://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"
Dim stylesRelationshipType = _
"https://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"
Dim wordmlNamespace = _
"https://schemas.openxmlformats.org/wordprocessingml/2006/main"
Using wdPackage As Package = Package.Open(fileName, FileMode.Open, FileAccess.ReadWrite)
Dim docPackageRelationship As PackageRelationship = wdPackage _
.GetRelationshipsByType(documentRelationshipType).FirstOrDefault()
If (docPackageRelationship IsNot Nothing) Then
Dim documentUri As Uri = PackUriHelper.ResolvePartUri(New Uri("/", _
UriKind.Relative), docPackageRelationship.TargetUri)
Dim documentPart As PackagePart = wdPackage.GetPart(documentUri)
' Load the document XML in the part into an XDocument instance.
Dim xDoc As XDocument = XDocument.Load(XmlReader.Create(documentPart.GetStream()))
' Find the styles part. There will only be one.
Dim styleRelation As PackageRelationship = documentPart _
.GetRelationshipsByType(stylesRelationshipType).FirstOrDefault()
Dim stylePart As PackagePart = Nothing
Dim styleDoc As XDocument = Nothing
If (styleRelation IsNot Nothing) Then
Dim styleUri As Uri = PackUriHelper.ResolvePartUri( _
documentUri, styleRelation.TargetUri)
stylePart = wdPackage.GetPart(styleUri)
' Load the style XML in the part into an XDocument instance.
styleDoc = XDocument.Load(XmlReader.Create(stylePart.GetStream()))
End If
Dim paraNode As XElement = xDoc.Root.<w:body>...<w:p>.FirstOrDefault()
Dim paraText As String = ParagraphText(paraNode)
' Remove all text runs.
paraNode...<w:r>.Remove()
paraNode.Add(<w:r><w:t><%= paraText.ToUpper() %></w:t></w:r>)
' Save the XML into the package.
Using xw As XmlWriter = _
XmlWriter.Create(documentPart.GetStream(FileMode.Create, FileAccess.Write))
xDoc.Save(xw)
End Using
Console.WriteLine("New first paragraph: >{0}<", paraText.ToUpper())
End If
End Using
End Sub
End Module
이 프로그램을 실행한 후 SampleDoc.docx를 열면 이 프로그램에서 해당 문서의 첫 번째 단락을 대문자로 변환한 것을 확인할 수 있습니다.
소스 Office Open XML 문서 만들기에서 설명하는 샘플 Open XML 문서를 사용하여 예제를 실행하는 경우 이 예제의 결과는 다음과 같습니다.
New first paragraph: >PARSING WORDPROCESSINGML WITH LINQ TO XML<