| EndProject | EndProject | ||||
| Global | Global | ||||
| GlobalSection(TeamFoundationVersionControl) = preSolution | GlobalSection(TeamFoundationVersionControl) = preSolution | ||||
| SccNumberOfProjects = 2 | |||||
| SccNumberOfProjects = 3 | |||||
| SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C} | SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C} | ||||
| SccTeamFoundationServer = https://tfs08.codeplex.com/ | SccTeamFoundationServer = https://tfs08.codeplex.com/ | ||||
| SccLocalPath0 = . | SccLocalPath0 = . | ||||
| SccProjectUniqueName1 = DocX\\DocX.csproj | SccProjectUniqueName1 = DocX\\DocX.csproj | ||||
| SccProjectName1 = DocX | SccProjectName1 = DocX | ||||
| SccLocalPath1 = DocX | SccLocalPath1 = DocX | ||||
| SccProjectUniqueName2 = ConsoleApplication1\\ConsoleApplication1.csproj | |||||
| SccProjectName2 = ConsoleApplication1 | |||||
| SccLocalPath2 = ConsoleApplication1 | |||||
| EndGlobalSection | EndGlobalSection | ||||
| GlobalSection(SolutionConfigurationPlatforms) = preSolution | GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||
| Debug|Any CPU = Debug|Any CPU | Debug|Any CPU = Debug|Any CPU |
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Xml.Linq; | |||||
| using System.Text.RegularExpressions; | |||||
| using System.IO.Packaging; | |||||
| using System.IO; | |||||
| namespace Novacode | |||||
| { | |||||
| public abstract class Container : DocXElement | |||||
| { | |||||
| /// <summary> | |||||
| /// Returns a list of all Paragraphs inside this container. | |||||
| /// </summary> | |||||
| /// <example> | |||||
| /// <code> | |||||
| /// Load a document. | |||||
| /// using (DocX document = DocX.Load(@"Test.docx")) | |||||
| /// { | |||||
| /// // All Paragraphs in this document. | |||||
| /// List<Paragraph> documentParagraphs = document.Paragraphs; | |||||
| /// | |||||
| /// // Make sure this document contains at least one Table. | |||||
| /// if (document.Tables.Count() > 0) | |||||
| /// { | |||||
| /// // Get the first Table in this document. | |||||
| /// Table t = document.Tables[0]; | |||||
| /// | |||||
| /// // All Paragraphs in this Table. | |||||
| /// List<Paragraph> tableParagraphs = t.Paragraphs; | |||||
| /// | |||||
| /// // Make sure this Table contains at least one Row. | |||||
| /// if (t.Rows.Count() > 0) | |||||
| /// { | |||||
| /// // Get the first Row in this document. | |||||
| /// Row r = t.Rows[0]; | |||||
| /// | |||||
| /// // All Paragraphs in this Row. | |||||
| /// List<Paragraph> rowParagraphs = r.Paragraphs; | |||||
| /// | |||||
| /// // Make sure this Row contains at least one Cell. | |||||
| /// if (r.Cells.Count() > 0) | |||||
| /// { | |||||
| /// // Get the first Cell in this document. | |||||
| /// Cell c = r.Cells[0]; | |||||
| /// | |||||
| /// // All Paragraphs in this Cell. | |||||
| /// List<Paragraph> cellParagraphs = c.Paragraphs; | |||||
| /// } | |||||
| /// } | |||||
| /// } | |||||
| /// | |||||
| /// // Save all changes to this document. | |||||
| /// document.Save(); | |||||
| /// }// Release this document from memory. | |||||
| /// </code> | |||||
| /// </example> | |||||
| public virtual List<Paragraph> Paragraphs | |||||
| { | |||||
| get | |||||
| { | |||||
| List<Paragraph> paragraphs = | |||||
| ( | |||||
| from p in Xml.Descendants(DocX.w + "p") | |||||
| select new Paragraph(Document, p, 0) | |||||
| ).ToList(); | |||||
| return paragraphs; | |||||
| } | |||||
| } | |||||
| public virtual List<Table> Tables | |||||
| { | |||||
| get | |||||
| { | |||||
| List<Table> tables = | |||||
| ( | |||||
| from t in Xml.Descendants(DocX.w + "tbl") | |||||
| select new Table(Document, t) | |||||
| ).ToList(); | |||||
| return tables; | |||||
| } | |||||
| } | |||||
| public virtual List<Hyperlink> Hyperlinks | |||||
| { | |||||
| get | |||||
| { | |||||
| List<Hyperlink> hyperlinks = new List<Hyperlink>(); | |||||
| foreach (Paragraph p in Paragraphs) | |||||
| hyperlinks.AddRange(p.Hyperlinks); | |||||
| return hyperlinks; | |||||
| } | |||||
| } | |||||
| public virtual List<Picture> Pictures | |||||
| { | |||||
| get | |||||
| { | |||||
| List<Picture> pictures = new List<Picture>(); | |||||
| foreach (Paragraph p in Paragraphs) | |||||
| pictures.AddRange(p.Pictures); | |||||
| return pictures; | |||||
| } | |||||
| } | |||||
| /// <summary> | |||||
| /// Sets the Direction of content. | |||||
| /// </summary> | |||||
| /// <param name="direction">Direction either LeftToRight or RightToLeft</param> | |||||
| /// <example> | |||||
| /// Set the Direction of content in a Paragraph to RightToLeft. | |||||
| /// <code> | |||||
| /// // Load a document. | |||||
| /// using (DocX document = DocX.Load(@"Test.docx")) | |||||
| /// { | |||||
| /// // Get the first Paragraph from this document. | |||||
| /// Paragraph p = document.InsertParagraph(); | |||||
| /// | |||||
| /// // Set the Direction of this Paragraph. | |||||
| /// p.Direction = Direction.RightToLeft; | |||||
| /// | |||||
| /// // Make sure the document contains at lest one Table. | |||||
| /// if (document.Tables.Count() > 0) | |||||
| /// { | |||||
| /// // Get the first Table from this document. | |||||
| /// Table t = document.Tables[0]; | |||||
| /// | |||||
| /// /* | |||||
| /// * Set the direction of the entire Table. | |||||
| /// * Note: The same function is available at the Row and Cell level. | |||||
| /// */ | |||||
| /// t.SetDirection(Direction.RightToLeft); | |||||
| /// } | |||||
| /// | |||||
| /// // Save all changes to this document. | |||||
| /// document.Save(); | |||||
| /// }// Release this document from memory. | |||||
| /// </code> | |||||
| /// </example> | |||||
| public virtual void SetDirection(Direction direction) | |||||
| { | |||||
| foreach (Paragraph p in Paragraphs) | |||||
| p.Direction = direction; | |||||
| } | |||||
| public virtual List<int> FindAll(string str) | |||||
| { | |||||
| return FindAll(str, RegexOptions.None); | |||||
| } | |||||
| public virtual List<int> FindAll(string str, RegexOptions options) | |||||
| { | |||||
| List<int> list = new List<int>(); | |||||
| foreach (Paragraph p in Paragraphs) | |||||
| { | |||||
| List<int> indexes = p.FindAll(str, options); | |||||
| for (int i = 0; i < indexes.Count(); i++) | |||||
| indexes[0] += p.startIndex; | |||||
| list.AddRange(indexes); | |||||
| } | |||||
| return list; | |||||
| } | |||||
| public virtual void ReplaceText(string oldValue, string newValue, bool trackChanges, RegexOptions options) | |||||
| { | |||||
| ReplaceText(oldValue, newValue, false, false, trackChanges, options, null, null, MatchFormattingOptions.SubsetMatch); | |||||
| } | |||||
| public virtual void ReplaceText(string oldValue, string newValue, bool includeHeaders, bool includeFooters, bool trackChanges, RegexOptions options) | |||||
| { | |||||
| ReplaceText(oldValue, newValue, includeHeaders, includeFooters, trackChanges, options, null, null, MatchFormattingOptions.SubsetMatch); | |||||
| } | |||||
| public virtual void ReplaceText(string oldValue, string newValue, bool includeHeaders, bool includeFooters, bool trackChanges, RegexOptions options, Formatting newFormatting, Formatting matchFormatting, MatchFormattingOptions fo) | |||||
| { | |||||
| foreach (Paragraph p in Paragraphs) | |||||
| p.ReplaceText(oldValue, newValue, trackChanges, options, newFormatting, matchFormatting, fo); | |||||
| } | |||||
| public virtual void ReplaceText(string oldValue, string newValue, bool trackChanges) | |||||
| { | |||||
| ReplaceText(oldValue, newValue, trackChanges, false, false, RegexOptions.None); | |||||
| } | |||||
| public virtual void ReplaceText(string oldValue, string newValue, bool includeHeaders, bool includeFooters, bool trackChanges) | |||||
| { | |||||
| ReplaceText(oldValue, newValue, includeHeaders, includeFooters, trackChanges, RegexOptions.None, null, null, MatchFormattingOptions.SubsetMatch); | |||||
| } | |||||
| public virtual Paragraph InsertParagraph(int index, string text, bool trackChanges) | |||||
| { | |||||
| return InsertParagraph(index, text, trackChanges, null); | |||||
| } | |||||
| public virtual Paragraph InsertParagraph() | |||||
| { | |||||
| return InsertParagraph(string.Empty, false); | |||||
| } | |||||
| public virtual Paragraph InsertParagraph(int index, Paragraph p) | |||||
| { | |||||
| XElement newXElement = new XElement(p.Xml); | |||||
| p.Xml = newXElement; | |||||
| Paragraph paragraph = HelperFunctions.GetFirstParagraphEffectedByInsert(Document, index); | |||||
| if (paragraph == null) | |||||
| Xml.Add(p.Xml); | |||||
| else | |||||
| { | |||||
| XElement[] split = HelperFunctions.SplitParagraph(paragraph, index - paragraph.startIndex); | |||||
| paragraph.Xml.ReplaceWith | |||||
| ( | |||||
| split[0], | |||||
| newXElement, | |||||
| split[1] | |||||
| ); | |||||
| } | |||||
| HelperFunctions.RebuildParagraphs(Document); | |||||
| return p; | |||||
| } | |||||
| public virtual Paragraph InsertParagraph(Paragraph p) | |||||
| { | |||||
| #region Styles | |||||
| XDocument style_document; | |||||
| if (p.styles.Count() > 0) | |||||
| { | |||||
| Uri style_package_uri = new Uri("/word/styles.xml", UriKind.Relative); | |||||
| if (!Document.package.PartExists(style_package_uri)) | |||||
| { | |||||
| PackagePart style_package = Document.package.CreatePart(style_package_uri, "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"); | |||||
| using (TextWriter tw = new StreamWriter(style_package.GetStream())) | |||||
| { | |||||
| style_document = new XDocument | |||||
| ( | |||||
| new XDeclaration("1.0", "UTF-8", "yes"), | |||||
| new XElement(XName.Get("styles", DocX.w.NamespaceName)) | |||||
| ); | |||||
| style_document.Save(tw); | |||||
| } | |||||
| } | |||||
| PackagePart styles_document = Document.package.GetPart(style_package_uri); | |||||
| using (TextReader tr = new StreamReader(styles_document.GetStream())) | |||||
| { | |||||
| style_document = XDocument.Load(tr); | |||||
| XElement styles_element = style_document.Element(XName.Get("styles", DocX.w.NamespaceName)); | |||||
| var ids = from d in styles_element.Descendants(XName.Get("style", DocX.w.NamespaceName)) | |||||
| let a = d.Attribute(XName.Get("styleId", DocX.w.NamespaceName)) | |||||
| where a != null | |||||
| select a.Value; | |||||
| foreach (XElement style in p.styles) | |||||
| { | |||||
| // If styles_element does not contain this element, then add it. | |||||
| if (!ids.Contains(style.Attribute(XName.Get("styleId", DocX.w.NamespaceName)).Value)) | |||||
| styles_element.Add(style); | |||||
| } | |||||
| } | |||||
| using (TextWriter tw = new StreamWriter(styles_document.GetStream())) | |||||
| style_document.Save(tw); | |||||
| } | |||||
| #endregion | |||||
| XElement newXElement = new XElement(p.Xml); | |||||
| Xml.Add(newXElement); | |||||
| int index = 0; | |||||
| if (Document.paragraphLookup.Keys.Count() > 0) | |||||
| { | |||||
| index = Document.paragraphLookup.Last().Key; | |||||
| if (Document.paragraphLookup.Last().Value.Text.Length == 0) | |||||
| index++; | |||||
| else | |||||
| index += Document.paragraphLookup.Last().Value.Text.Length; | |||||
| } | |||||
| Paragraph newParagraph = new Paragraph(Document, newXElement, index); | |||||
| Document.paragraphLookup.Add(index, newParagraph); | |||||
| return newParagraph; | |||||
| } | |||||
| public virtual Paragraph InsertParagraph(int index, string text, bool trackChanges, Formatting formatting) | |||||
| { | |||||
| Paragraph newParagraph = new Paragraph(Document, new XElement(DocX.w + "p"), index); | |||||
| newParagraph.InsertText(0, text, trackChanges, formatting); | |||||
| Paragraph firstPar = HelperFunctions.GetFirstParagraphEffectedByInsert(Document, index); | |||||
| if (firstPar != null) | |||||
| { | |||||
| XElement[] splitParagraph = HelperFunctions.SplitParagraph(firstPar, index - firstPar.startIndex); | |||||
| firstPar.Xml.ReplaceWith | |||||
| ( | |||||
| splitParagraph[0], | |||||
| newParagraph.Xml, | |||||
| splitParagraph[1] | |||||
| ); | |||||
| } | |||||
| else | |||||
| Xml.Add(newParagraph); | |||||
| HelperFunctions.RebuildParagraphs(Document); | |||||
| return newParagraph; | |||||
| } | |||||
| public virtual Paragraph InsertParagraph(string text) | |||||
| { | |||||
| return InsertParagraph(text, false, new Formatting()); | |||||
| } | |||||
| public virtual Paragraph InsertParagraph(string text, bool trackChanges) | |||||
| { | |||||
| return InsertParagraph(text, trackChanges, new Formatting()); | |||||
| } | |||||
| public virtual Paragraph InsertParagraph(string text, bool trackChanges, Formatting formatting) | |||||
| { | |||||
| XElement newParagraph = new XElement | |||||
| ( | |||||
| XName.Get("p", DocX.w.NamespaceName), new XElement(XName.Get("pPr", DocX.w.NamespaceName)), HelperFunctions.FormatInput(text, formatting.Xml) | |||||
| ); | |||||
| if (trackChanges) | |||||
| newParagraph = HelperFunctions.CreateEdit(EditType.ins, DateTime.Now, newParagraph); | |||||
| Xml.Add(newParagraph); | |||||
| HelperFunctions.RebuildParagraphs(Document); | |||||
| return Paragraphs.Last(); | |||||
| } | |||||
| internal Container(DocX document, XElement xml) | |||||
| : base(document, xml) | |||||
| { | |||||
| } | |||||
| } | |||||
| } |
| </Reference> | </Reference> | ||||
| </ItemGroup> | </ItemGroup> | ||||
| <ItemGroup> | <ItemGroup> | ||||
| <Compile Include="Container.cs" /> | |||||
| <Compile Include="Footers.cs" /> | |||||
| <Compile Include="Footer.cs" /> | |||||
| <Compile Include="CustomProperty.cs" /> | <Compile Include="CustomProperty.cs" /> | ||||
| <Compile Include="DocProperty.cs" /> | <Compile Include="DocProperty.cs" /> | ||||
| <Compile Include="Header.cs" /> | |||||
| <Compile Include="Headers.cs" /> | |||||
| <Compile Include="HelperFunctions.cs" /> | |||||
| <Compile Include="Hyperlink.cs" /> | <Compile Include="Hyperlink.cs" /> | ||||
| <Compile Include="_BaseClasses.cs" /> | <Compile Include="_BaseClasses.cs" /> | ||||
| <Compile Include="Table.cs" /> | <Compile Include="Table.cs" /> | ||||
| </Compile> | </Compile> | ||||
| </ItemGroup> | </ItemGroup> | ||||
| <ItemGroup> | <ItemGroup> | ||||
| <None Include="Help\Changes in this version 1.0.0.9.docx" /> | |||||
| <None Include="Help\DocX v1.0.0.9 - Documentation.chm" /> | |||||
| <None Include="Help\Changes in this version 1.0.0.10.docx" /> | |||||
| <None Include="Help\DocX v1.0.0.10 - Documentation.chm" /> | |||||
| <None Include="Help\Read Me.docx" /> | <None Include="Help\Read Me.docx" /> | ||||
| <None Include="StrongNameKey.pfx" /> | <None Include="StrongNameKey.pfx" /> | ||||
| </ItemGroup> | </ItemGroup> |
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Xml.Linq; | |||||
| using System.IO.Packaging; | |||||
| namespace Novacode | |||||
| { | |||||
| public class Footer : Container | |||||
| { | |||||
| PackagePart mainPart; | |||||
| internal Footer(DocX document, XElement xml, PackagePart mainPart): base(document, xml) | |||||
| { | |||||
| this.mainPart = mainPart; | |||||
| } | |||||
| public override Paragraph InsertParagraph() | |||||
| { | |||||
| Paragraph p = base.InsertParagraph(); | |||||
| p.PackagePart = mainPart; | |||||
| return p; | |||||
| } | |||||
| public override Paragraph InsertParagraph(int index, string text, bool trackChanges) | |||||
| { | |||||
| Paragraph p = base.InsertParagraph(index, text, trackChanges); | |||||
| p.PackagePart = mainPart; | |||||
| return p; | |||||
| } | |||||
| public override Paragraph InsertParagraph(Paragraph p) | |||||
| { | |||||
| p.PackagePart = mainPart; | |||||
| return base.InsertParagraph(p); | |||||
| } | |||||
| public override Paragraph InsertParagraph(int index, Paragraph p) | |||||
| { | |||||
| p.PackagePart = mainPart; | |||||
| return base.InsertParagraph(index, p); | |||||
| } | |||||
| public override Paragraph InsertParagraph(int index, string text, bool trackChanges, Formatting formatting) | |||||
| { | |||||
| Paragraph p = base.InsertParagraph(index, text, trackChanges, formatting); | |||||
| p.PackagePart = mainPart; | |||||
| return p; | |||||
| } | |||||
| public override Paragraph InsertParagraph(string text) | |||||
| { | |||||
| Paragraph p = base.InsertParagraph(text); | |||||
| p.PackagePart = mainPart; | |||||
| return p; | |||||
| } | |||||
| public override Paragraph InsertParagraph(string text, bool trackChanges) | |||||
| { | |||||
| Paragraph p = base.InsertParagraph(text, trackChanges); | |||||
| p.PackagePart = mainPart; | |||||
| return p; | |||||
| } | |||||
| public override Paragraph InsertParagraph(string text, bool trackChanges, Formatting formatting) | |||||
| { | |||||
| Paragraph p = base.InsertParagraph(text, trackChanges, formatting); | |||||
| p.PackagePart = mainPart; | |||||
| return p; | |||||
| } | |||||
| } | |||||
| } |
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| namespace Novacode | |||||
| { | |||||
| public class Footers | |||||
| { | |||||
| internal Footers() | |||||
| { | |||||
| } | |||||
| public Footer odd; | |||||
| public Footer even; | |||||
| public Footer first; | |||||
| } | |||||
| } |
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Xml.Linq; | |||||
| using System.IO.Packaging; | |||||
| namespace Novacode | |||||
| { | |||||
| public class Header : Container | |||||
| { | |||||
| PackagePart mainPart; | |||||
| internal Header(DocX document, XElement xml, PackagePart mainPart):base(document, xml) | |||||
| { | |||||
| this.mainPart = mainPart; | |||||
| } | |||||
| public override Paragraph InsertParagraph() | |||||
| { | |||||
| Paragraph p = base.InsertParagraph(); | |||||
| p.PackagePart = mainPart; | |||||
| return p; | |||||
| } | |||||
| public override Paragraph InsertParagraph(int index, string text, bool trackChanges) | |||||
| { | |||||
| Paragraph p = base.InsertParagraph(index, text, trackChanges); | |||||
| p.PackagePart = mainPart; | |||||
| return p; | |||||
| } | |||||
| public override Paragraph InsertParagraph(Paragraph p) | |||||
| { | |||||
| p.PackagePart = mainPart; | |||||
| return base.InsertParagraph(p); | |||||
| } | |||||
| public override Paragraph InsertParagraph(int index, Paragraph p) | |||||
| { | |||||
| p.PackagePart = mainPart; | |||||
| return base.InsertParagraph(index, p); | |||||
| } | |||||
| public override Paragraph InsertParagraph(int index, string text, bool trackChanges, Formatting formatting) | |||||
| { | |||||
| Paragraph p = base.InsertParagraph(index, text, trackChanges, formatting); | |||||
| p.PackagePart = mainPart; | |||||
| return p; | |||||
| } | |||||
| public override Paragraph InsertParagraph(string text) | |||||
| { | |||||
| Paragraph p = base.InsertParagraph(text); | |||||
| p.PackagePart = mainPart; | |||||
| return p; | |||||
| } | |||||
| public override Paragraph InsertParagraph(string text, bool trackChanges) | |||||
| { | |||||
| Paragraph p = base.InsertParagraph(text, trackChanges); | |||||
| p.PackagePart = mainPart; | |||||
| return p; | |||||
| } | |||||
| public override Paragraph InsertParagraph(string text, bool trackChanges, Formatting formatting) | |||||
| { | |||||
| Paragraph p = base.InsertParagraph(text, trackChanges, formatting); | |||||
| p.PackagePart = mainPart; | |||||
| return p; | |||||
| } | |||||
| } | |||||
| } |
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| namespace Novacode | |||||
| { | |||||
| public class Headers | |||||
| { | |||||
| internal Headers() | |||||
| { | |||||
| } | |||||
| public Header odd; | |||||
| public Header even; | |||||
| public Header first; | |||||
| } | |||||
| } |
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.IO.Packaging; | |||||
| using System.Xml.Linq; | |||||
| using System.IO; | |||||
| using System.Reflection; | |||||
| using System.IO.Compression; | |||||
| using System.Security.Principal; | |||||
| namespace Novacode | |||||
| { | |||||
| internal static class HelperFunctions | |||||
| { | |||||
| internal static PackagePart CreateOrGetSettingsPart(Package package) | |||||
| { | |||||
| PackagePart settingsPart; | |||||
| Uri settingsUri = new Uri("/word/settings.xml", UriKind.Relative); | |||||
| if (!package.PartExists(settingsUri)) | |||||
| { | |||||
| settingsPart = package.CreatePart(settingsUri, "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"); | |||||
| PackagePart mainDocumentPart = package.GetParts().Where | |||||
| ( | |||||
| p => p.ContentType.Equals | |||||
| ( | |||||
| "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml", | |||||
| StringComparison.CurrentCultureIgnoreCase | |||||
| ) | |||||
| ).Single(); | |||||
| mainDocumentPart.CreateRelationship(settingsUri, TargetMode.Internal, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings"); | |||||
| XDocument settings = XDocument.Parse | |||||
| (@"<?xml version='1.0' encoding='utf-8' standalone='yes'?> | |||||
| <w:settings xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:r='http://schemas.openxmlformats.org/officeDocument/2006/relationships' xmlns:m='http://schemas.openxmlformats.org/officeDocument/2006/math' xmlns:v='urn:schemas-microsoft-com:vml' xmlns:w10='urn:schemas-microsoft-com:office:word' xmlns:w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' xmlns:sl='http://schemas.openxmlformats.org/schemaLibrary/2006/main'> | |||||
| <w:zoom w:percent='100' /> | |||||
| <w:defaultTabStop w:val='720' /> | |||||
| <w:characterSpacingControl w:val='doNotCompress' /> | |||||
| <w:compat /> | |||||
| <w:rsids> | |||||
| <w:rsidRoot w:val='00217F62' /> | |||||
| <w:rsid w:val='001915A3' /> | |||||
| <w:rsid w:val='00217F62' /> | |||||
| <w:rsid w:val='00A906D8' /> | |||||
| <w:rsid w:val='00AB5A74' /> | |||||
| <w:rsid w:val='00F071AE' /> | |||||
| </w:rsids> | |||||
| <m:mathPr> | |||||
| <m:mathFont m:val='Cambria Math' /> | |||||
| <m:brkBin m:val='before' /> | |||||
| <m:brkBinSub m:val='--' /> | |||||
| <m:smallFrac m:val='off' /> | |||||
| <m:dispDef /> | |||||
| <m:lMargin m:val='0' /> | |||||
| <m:rMargin m:val='0' /> | |||||
| <m:defJc m:val='centerGroup' /> | |||||
| <m:wrapIndent m:val='1440' /> | |||||
| <m:intLim m:val='subSup' /> | |||||
| <m:naryLim m:val='undOvr' /> | |||||
| </m:mathPr> | |||||
| <w:themeFontLang w:val='en-IE' w:bidi='ar-SA' /> | |||||
| <w:clrSchemeMapping w:bg1='light1' w:t1='dark1' w:bg2='light2' w:t2='dark2' w:accent1='accent1' w:accent2='accent2' w:accent3='accent3' w:accent4='accent4' w:accent5='accent5' w:accent6='accent6' w:hyperlink='hyperlink' w:followedHyperlink='followedHyperlink' /> | |||||
| <w:shapeDefaults> | |||||
| <o:shapedefaults v:ext='edit' spidmax='2050' /> | |||||
| <o:shapelayout v:ext='edit'> | |||||
| <o:idmap v:ext='edit' data='1' /> | |||||
| </o:shapelayout> | |||||
| </w:shapeDefaults> | |||||
| <w:decimalSymbol w:val='.' /> | |||||
| <w:listSeparator w:val=',' /> | |||||
| </w:settings>" | |||||
| ); | |||||
| // Save the settings document. | |||||
| using (TextWriter tw = new StreamWriter(settingsPart.GetStream())) | |||||
| settings.Save(tw); | |||||
| } | |||||
| else | |||||
| settingsPart = package.GetPart(settingsUri); | |||||
| return settingsPart; | |||||
| } | |||||
| internal static void CreateCustomPropertiesPart(DocX document) | |||||
| { | |||||
| PackagePart customPropertiesPart = document.package.CreatePart(new Uri("/docProps/custom.xml", UriKind.Relative), "application/vnd.openxmlformats-officedocument.custom-properties+xml"); | |||||
| XDocument customPropDoc = new XDocument | |||||
| ( | |||||
| new XDeclaration("1.0", "UTF-8", "yes"), | |||||
| new XElement | |||||
| ( | |||||
| XName.Get("Properties", DocX.customPropertiesSchema.NamespaceName), | |||||
| new XAttribute(XNamespace.Xmlns + "vt", DocX.customVTypesSchema) | |||||
| ) | |||||
| ); | |||||
| using (TextWriter tw = new StreamWriter(customPropertiesPart.GetStream(FileMode.Create, FileAccess.Write))) | |||||
| customPropDoc.Save(tw, SaveOptions.DisableFormatting); | |||||
| document.package.CreateRelationship(customPropertiesPart.Uri, TargetMode.Internal, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties"); | |||||
| } | |||||
| internal static XDocument DecompressXMLResource(string manifest_resource_name) | |||||
| { | |||||
| // XDocument to load the compressed Xml resource into. | |||||
| XDocument document; | |||||
| // Get a reference to the executing assembly. | |||||
| Assembly assembly = Assembly.GetExecutingAssembly(); | |||||
| // Open a Stream to the embedded resource. | |||||
| Stream stream = assembly.GetManifestResourceStream(manifest_resource_name); | |||||
| // Decompress the embedded resource. | |||||
| using (GZipStream zip = new GZipStream(stream, CompressionMode.Decompress)) | |||||
| { | |||||
| // Load this decompressed embedded resource into an XDocument using a TextReader. | |||||
| using (TextReader sr = new StreamReader(zip)) | |||||
| { | |||||
| document = XDocument.Load(sr); | |||||
| } | |||||
| } | |||||
| // Return the decompressed Xml as an XDocument. | |||||
| return document; | |||||
| } | |||||
| /// <summary> | |||||
| /// If this document does not contain a /word/styles.xml add the default one generated by Microsoft Word. | |||||
| /// </summary> | |||||
| /// <param name="package"></param> | |||||
| /// <param name="mainDocumentPart"></param> | |||||
| /// <returns></returns> | |||||
| internal static XDocument AddDefaultStylesXml(Package package) | |||||
| { | |||||
| XDocument stylesDoc; | |||||
| // Create the main document part for this package | |||||
| PackagePart word_styles = package.CreatePart(new Uri("/word/styles.xml", UriKind.Relative), "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"); | |||||
| stylesDoc = HelperFunctions.DecompressXMLResource("Novacode.Resources.default_styles.xml.gz"); | |||||
| // Save /word/styles.xml | |||||
| using (TextWriter tw = new StreamWriter(word_styles.GetStream(FileMode.Create, FileAccess.Write))) | |||||
| stylesDoc.Save(tw, SaveOptions.DisableFormatting); | |||||
| PackagePart mainDocumentPart = package.GetParts().Where | |||||
| ( | |||||
| p => p.ContentType.Equals | |||||
| ( | |||||
| "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml", | |||||
| StringComparison.CurrentCultureIgnoreCase | |||||
| ) | |||||
| ).Single(); | |||||
| mainDocumentPart.CreateRelationship(word_styles.Uri, TargetMode.Internal, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"); | |||||
| return stylesDoc; | |||||
| } | |||||
| static internal XElement CreateEdit(EditType t, DateTime edit_time, object content) | |||||
| { | |||||
| if (t == EditType.del) | |||||
| { | |||||
| foreach (object o in (IEnumerable<XElement>)content) | |||||
| { | |||||
| if (o is XElement) | |||||
| { | |||||
| XElement e = (o as XElement); | |||||
| IEnumerable<XElement> ts = e.DescendantsAndSelf(XName.Get("t", DocX.w.NamespaceName)); | |||||
| for (int i = 0; i < ts.Count(); i++) | |||||
| { | |||||
| XElement text = ts.ElementAt(i); | |||||
| text.ReplaceWith(new XElement(DocX.w + "delText", text.Attributes(), text.Value)); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| return | |||||
| ( | |||||
| new XElement(DocX.w + t.ToString(), | |||||
| new XAttribute(DocX.w + "id", 0), | |||||
| new XAttribute(DocX.w + "author", WindowsIdentity.GetCurrent().Name), | |||||
| new XAttribute(DocX.w + "date", edit_time), | |||||
| content) | |||||
| ); | |||||
| } | |||||
| internal static XElement CreateTable(int rowCount, int coloumnCount) | |||||
| { | |||||
| XElement newTable = | |||||
| new XElement | |||||
| ( | |||||
| XName.Get("tbl", DocX.w.NamespaceName), | |||||
| new XElement | |||||
| ( | |||||
| XName.Get("tblPr", DocX.w.NamespaceName), | |||||
| new XElement(XName.Get("tblStyle", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), "TableGrid")), | |||||
| new XElement(XName.Get("tblW", DocX.w.NamespaceName), new XAttribute(XName.Get("w", DocX.w.NamespaceName), "5000"), new XAttribute(XName.Get("type", DocX.w.NamespaceName), "auto")), | |||||
| new XElement(XName.Get("tblLook", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), "04A0")) | |||||
| ) | |||||
| ); | |||||
| XElement tableGrid = new XElement(XName.Get("tblGrid", DocX.w.NamespaceName)); | |||||
| for (int i = 0; i < coloumnCount; i++) | |||||
| tableGrid.Add(new XElement(XName.Get("gridCol", DocX.w.NamespaceName), new XAttribute(XName.Get("w", DocX.w.NamespaceName), "2310"))); | |||||
| newTable.Add(tableGrid); | |||||
| for (int i = 0; i < rowCount; i++) | |||||
| { | |||||
| XElement row = new XElement(XName.Get("tr", DocX.w.NamespaceName)); | |||||
| for (int j = 0; j < coloumnCount; j++) | |||||
| { | |||||
| XElement cell = | |||||
| new XElement | |||||
| ( | |||||
| XName.Get("tc", DocX.w.NamespaceName), | |||||
| new XElement(XName.Get("tcPr", DocX.w.NamespaceName), | |||||
| new XElement(XName.Get("tcW", DocX.w.NamespaceName), new XAttribute(XName.Get("w", DocX.w.NamespaceName), "2310"), new XAttribute(XName.Get("type", DocX.w.NamespaceName), "dxa"))), | |||||
| new XElement(XName.Get("p", DocX.w.NamespaceName), new XElement(XName.Get("pPr", DocX.w.NamespaceName))) | |||||
| ); | |||||
| row.Add(cell); | |||||
| } | |||||
| newTable.Add(row); | |||||
| } | |||||
| return newTable; | |||||
| } | |||||
| internal static void RenumberIDs(DocX document) | |||||
| { | |||||
| IEnumerable<XAttribute> trackerIDs = | |||||
| (from d in document.mainDoc.Descendants() | |||||
| where d.Name.LocalName == "ins" || d.Name.LocalName == "del" | |||||
| select d.Attribute(XName.Get("id", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"))); | |||||
| for (int i = 0; i < trackerIDs.Count(); i++) | |||||
| trackerIDs.ElementAt(i).Value = i.ToString(); | |||||
| } | |||||
| static internal Paragraph GetFirstParagraphEffectedByInsert(DocX document, int index) | |||||
| { | |||||
| // This document contains no Paragraphs and insertion is at index 0 | |||||
| if (document.paragraphLookup.Keys.Count() == 0 && index == 0) | |||||
| return null; | |||||
| foreach (int paragraphEndIndex in document.paragraphLookup.Keys) | |||||
| { | |||||
| if (paragraphEndIndex >= index) | |||||
| return document.paragraphLookup[paragraphEndIndex]; | |||||
| } | |||||
| throw new ArgumentOutOfRangeException(); | |||||
| } | |||||
| internal static List<XElement> FormatInput(string text, XElement rPr) | |||||
| { | |||||
| List<XElement> newRuns = new List<XElement>(); | |||||
| XElement tabRun = new XElement(DocX.w + "tab"); | |||||
| XElement breakRun = new XElement(DocX.w + "br"); | |||||
| StringBuilder sb = new StringBuilder(); | |||||
| foreach (char c in text) | |||||
| { | |||||
| switch (c) | |||||
| { | |||||
| case '\t': | |||||
| if (sb.Length > 0) | |||||
| { | |||||
| XElement t = new XElement(DocX.w + "t", sb.ToString()); | |||||
| Novacode.Text.PreserveSpace(t); | |||||
| newRuns.Add(new XElement(DocX.w + "r", rPr, t)); | |||||
| sb = new StringBuilder(); | |||||
| } | |||||
| newRuns.Add(new XElement(DocX.w + "r", rPr, tabRun)); | |||||
| break; | |||||
| case '\n': | |||||
| if (sb.Length > 0) | |||||
| { | |||||
| XElement t = new XElement(DocX.w + "t", sb.ToString()); | |||||
| Novacode.Text.PreserveSpace(t); | |||||
| newRuns.Add(new XElement(DocX.w + "r", rPr, t)); | |||||
| sb = new StringBuilder(); | |||||
| } | |||||
| newRuns.Add(new XElement(DocX.w + "r", rPr, breakRun)); | |||||
| break; | |||||
| default: | |||||
| sb.Append(c); | |||||
| break; | |||||
| } | |||||
| } | |||||
| if (sb.Length > 0) | |||||
| { | |||||
| XElement t = new XElement(DocX.w + "t", sb.ToString()); | |||||
| Novacode.Text.PreserveSpace(t); | |||||
| newRuns.Add(new XElement(DocX.w + "r", rPr, t)); | |||||
| } | |||||
| return newRuns; | |||||
| } | |||||
| static internal XElement[] SplitParagraph(Paragraph p, int index) | |||||
| { | |||||
| Run r = p.GetFirstRunEffectedByInsert(index); | |||||
| XElement[] split; | |||||
| XElement before, after; | |||||
| if (r.Xml.Parent.Name.LocalName == "ins") | |||||
| { | |||||
| split = p.SplitEdit(r.Xml.Parent, index, EditType.ins); | |||||
| before = new XElement(p.Xml.Name, p.Xml.Attributes(), r.Xml.Parent.ElementsBeforeSelf(), split[0]); | |||||
| after = new XElement(p.Xml.Name, p.Xml.Attributes(), r.Xml.Parent.ElementsAfterSelf(), split[1]); | |||||
| } | |||||
| else if (r.Xml.Parent.Name.LocalName == "del") | |||||
| { | |||||
| split = p.SplitEdit(r.Xml.Parent, index, EditType.del); | |||||
| before = new XElement(p.Xml.Name, p.Xml.Attributes(), r.Xml.Parent.ElementsBeforeSelf(), split[0]); | |||||
| after = new XElement(p.Xml.Name, p.Xml.Attributes(), r.Xml.Parent.ElementsAfterSelf(), split[1]); | |||||
| } | |||||
| else | |||||
| { | |||||
| split = Run.SplitRun(r, index); | |||||
| before = new XElement(p.Xml.Name, p.Xml.Attributes(), r.Xml.ElementsBeforeSelf(), split[0]); | |||||
| after = new XElement(p.Xml.Name, p.Xml.Attributes(), split[1], r.Xml.ElementsAfterSelf()); | |||||
| } | |||||
| if (before.Elements().Count() == 0) | |||||
| before = null; | |||||
| if (after.Elements().Count() == 0) | |||||
| after = null; | |||||
| return new XElement[] { before, after }; | |||||
| } | |||||
| static internal void RebuildParagraphs(DocX document) | |||||
| { | |||||
| document.paragraphLookup.Clear(); | |||||
| document.paragraphs.Clear(); | |||||
| // Get the runs in this paragraph | |||||
| IEnumerable<XElement> paras = document.mainDoc.Descendants(XName.Get("p", "http://schemas.openxmlformats.org/wordprocessingml/2006/main")); | |||||
| int startIndex = 0; | |||||
| // Loop through each run in this paragraph | |||||
| foreach (XElement par in paras) | |||||
| { | |||||
| Paragraph xp = new Paragraph(document, par, startIndex); | |||||
| // Add to paragraph list | |||||
| document.paragraphs.Add(xp); | |||||
| // Only add runs which contain text | |||||
| if (Paragraph.GetElementTextLength(par) > 0) | |||||
| { | |||||
| document.paragraphLookup.Add(xp.endIndex, xp); | |||||
| startIndex = xp.endIndex; | |||||
| } | |||||
| } | |||||
| } | |||||
| /// <!-- | |||||
| /// Bug found and fixed by trnilse. To see the change, | |||||
| /// please compare this release to the previous release using TFS compare. | |||||
| /// --> | |||||
| static internal bool IsSameFile(Stream streamOne, Stream streamTwo) | |||||
| { | |||||
| int file1byte, file2byte; | |||||
| if (streamOne.Length != streamOne.Length) | |||||
| { | |||||
| // Return false to indicate files are different | |||||
| return false; | |||||
| } | |||||
| // Read and compare a byte from each file until either a | |||||
| // non-matching set of bytes is found or until the end of | |||||
| // file1 is reached. | |||||
| do | |||||
| { | |||||
| // Read one byte from each file. | |||||
| file1byte = streamOne.ReadByte(); | |||||
| file2byte = streamTwo.ReadByte(); | |||||
| } | |||||
| while ((file1byte == file2byte) && (file1byte != -1)); | |||||
| // Return the success of the comparison. "file1byte" is | |||||
| // equal to "file2byte" at this point only if the files are | |||||
| // the same. | |||||
| streamOne.Position = 0; | |||||
| streamTwo.Position = 0; | |||||
| return ((file1byte - file2byte) == 0); | |||||
| } | |||||
| } | |||||
| } |
| /// </summary> | /// </summary> | ||||
| public class Hyperlink: DocXElement | public class Hyperlink: DocXElement | ||||
| { | { | ||||
| internal Uri uri; | |||||
| internal Dictionary<PackagePart, PackageRelationship> hyperlink_rels; | |||||
| /// <summary> | |||||
| /// Remove a Hyperlink from this Paragraph only. | |||||
| /// </summary> | |||||
| /// <example> | |||||
| /// <code> | |||||
| /// // Create a document. | |||||
| /// using (DocX document = DocX.Create(@"Test.docx")) | |||||
| /// { | |||||
| /// // Add a hyperlink to this document. | |||||
| /// Hyperlink h = document.AddHyperlink("link", new Uri("http://www.google.com")); | |||||
| /// | |||||
| /// // Add a Paragraph to this document and insert the hyperlink | |||||
| /// Paragraph p1 = document.InsertParagraph(); | |||||
| /// p1.Append("This is a cool ").AppendHyperlink(h).Append(" ."); | |||||
| /// | |||||
| /// /* | |||||
| /// * Remove the hyperlink from this Paragraph only. | |||||
| /// * Note a reference to the hyperlink will still exist in the document and it can thus be reused. | |||||
| /// */ | |||||
| /// p1.Hyperlinks[0].Remove(); | |||||
| /// | |||||
| /// // Add a new Paragraph to this document and reuse the hyperlink h. | |||||
| /// Paragraph p2 = document.InsertParagraph(); | |||||
| /// p2.Append("This is the same cool ").AppendHyperlink(h).Append(" ."); | |||||
| /// | |||||
| /// document.Save(); | |||||
| /// }// Release this document from memory. | |||||
| /// </code> | |||||
| /// </example> | |||||
| public void Remove() | |||||
| { | |||||
| Xml.Remove(); | |||||
| } | |||||
| /// <summary> | /// <summary> | ||||
| /// Change the Text of a Hyperlink. | /// Change the Text of a Hyperlink. | ||||
| /// </summary> | /// </summary> | ||||
| ); | ); | ||||
| // Format and add the new text. | // Format and add the new text. | ||||
| List<XElement> newRuns = DocX.FormatInput(value, rPr); | |||||
| List<XElement> newRuns = HelperFunctions.FormatInput(value, rPr); | |||||
| Xml.Add(newRuns); | Xml.Add(newRuns); | ||||
| } | } | ||||
| } | } | ||||
| // Return the Id of this Hyperlink. | |||||
| internal string GetId() | |||||
| { | |||||
| return Xml.Attribute(DocX.r + "id").Value; | |||||
| } | |||||
| /// <summary> | /// <summary> | ||||
| /// Change the Uri of a Hyperlink. | /// Change the Uri of a Hyperlink. | ||||
| /// </summary> | /// </summary> | ||||
| public Uri Uri | public Uri Uri | ||||
| { | { | ||||
| get | get | ||||
| { | |||||
| // Get the word\document.xml part | |||||
| PackagePart word_document = Document.package.GetPart(new Uri("/word/document.xml", UriKind.Relative)); | |||||
| // Get the Hyperlink relation based on its Id. | |||||
| PackageRelationship r = word_document.GetRelationship(GetId()); | |||||
| { | |||||
| // Return the Hyperlinks Uri. | // Return the Hyperlinks Uri. | ||||
| return r.TargetUri; | |||||
| return uri; | |||||
| } | } | ||||
| set | set | ||||
| { | { | ||||
| // Get the word\document.xml part | |||||
| PackagePart word_document = Document.package.GetPart(new Uri("/word/document.xml", UriKind.Relative)); | |||||
| foreach (PackagePart p in hyperlink_rels.Keys) | |||||
| { | |||||
| PackageRelationship r = hyperlink_rels[p]; | |||||
| // Get the Hyperlink relation based on its Id. | |||||
| PackageRelationship r = word_document.GetRelationship(GetId()); | |||||
| // Get all of the information about this relationship. | |||||
| TargetMode r_tm = r.TargetMode; | |||||
| string r_rt = r.RelationshipType; | |||||
| string r_id = r.Id; | |||||
| // Get all of the information about this relationship. | |||||
| TargetMode r_tm = r.TargetMode; | |||||
| string r_rt = r.RelationshipType; | |||||
| string r_id = r.Id; | |||||
| // Delete the relationship | |||||
| p.DeleteRelationship(r_id); | |||||
| p.CreateRelationship(value, r_tm, r_rt, r_id); | |||||
| } | |||||
| // Delete the relationship | |||||
| word_document.DeleteRelationship(r_id); | |||||
| word_document.CreateRelationship(value, r_tm, r_rt, r_id); | |||||
| uri = value; | |||||
| } | } | ||||
| } | } | ||||
| internal Hyperlink(DocX document, XElement i): base(document, i) | internal Hyperlink(DocX document, XElement i): base(document, i) | ||||
| { | { | ||||
| hyperlink_rels = new Dictionary<PackagePart, PackageRelationship>(); | |||||
| } | } | ||||
| } | } | ||||
| } | } |
| /// </summary> | /// </summary> | ||||
| private string id; | private string id; | ||||
| private DocX document; | private DocX document; | ||||
| internal PackageRelationship pr; | |||||
| /// <summary> | /// <summary> | ||||
| /// Returns the id of this Image. | /// Returns the id of this Image. | ||||
| internal Image(DocX document, PackageRelationship pr) | internal Image(DocX document, PackageRelationship pr) | ||||
| { | { | ||||
| this.document = document; | this.document = document; | ||||
| this.pr = pr; | |||||
| this.id = pr.Id; | this.id = pr.Id; | ||||
| } | } | ||||
| /// </summary> | /// </summary> | ||||
| public class Paragraph : InsertBeforeOrAfter | public class Paragraph : InsertBeforeOrAfter | ||||
| { | { | ||||
| PackagePart mainPart; | |||||
| public PackagePart PackagePart { get { return mainPart; } set { mainPart = value; } } | |||||
| internal List<XElement> runs; | internal List<XElement> runs; | ||||
| // This paragraphs text alignment | // This paragraphs text alignment | ||||
| ( | ( | ||||
| from p in Xml.Descendants() | from p in Xml.Descendants() | ||||
| where (p.Name.LocalName == "drawing") | where (p.Name.LocalName == "drawing") | ||||
| select new Picture(Document, p) | |||||
| let id = | |||||
| ( | |||||
| from e in p.Descendants() | |||||
| where e.Name.LocalName.Equals("blip") | |||||
| select e.Attribute(XName.Get("embed", "http://schemas.openxmlformats.org/officeDocument/2006/relationships")).Value | |||||
| ).Single() | |||||
| let img = new Image(Document, mainPart.GetRelationship(id)) | |||||
| select new Picture(Document, p, img) | |||||
| ).ToList(); | ).ToList(); | ||||
| return pictures; | return pictures; | ||||
| } | } | ||||
| } | } | ||||
| BuildRunLookup(xml); | BuildRunLookup(xml); | ||||
| // Get all of the images in this document | // Get all of the images in this document | ||||
| pictures = (from i in xml.Descendants(XName.Get("drawing", DocX.w.NamespaceName)) | |||||
| select new Picture(Document, i)).ToList(); | |||||
| pictures = | |||||
| ( | |||||
| from i in xml.Descendants(XName.Get("drawing", DocX.w.NamespaceName)) | |||||
| let id = | |||||
| ( | |||||
| from e in Xml.Descendants() | |||||
| where e.Name.LocalName.Equals("blip") | |||||
| select e.Attribute(XName.Get("embed", "http://schemas.openxmlformats.org/officeDocument/2006/relationships")).Value | |||||
| ).Single() | |||||
| let img = new Image(Document, mainPart.GetRelationship(id)) | |||||
| select new Picture(Document, i, img) | |||||
| ).ToList(); | |||||
| RebuildDocProperties(); | RebuildDocProperties(); | ||||
| var styles_element_ids = stylesElements.Select(e => e.Attribute(XName.Get("val", DocX.w.NamespaceName)).Value); | var styles_element_ids = stylesElements.Select(e => e.Attribute(XName.Get("val", DocX.w.NamespaceName)).Value); | ||||
| foreach(string id in styles_element_ids) | |||||
| { | |||||
| var style = | |||||
| ( | |||||
| from d in styles_element.Descendants() | |||||
| let styleId = d.Attribute(XName.Get("styleId", DocX.w.NamespaceName)) | |||||
| let type = d.Attribute(XName.Get("type", DocX.w.NamespaceName)) | |||||
| where type != null && type.Value == "paragraph" && styleId != null && styleId.Value == id | |||||
| select d | |||||
| ).First(); | |||||
| styles.Add(style); | |||||
| } | |||||
| //foreach(string id in styles_element_ids) | |||||
| //{ | |||||
| // var style = | |||||
| // ( | |||||
| // from d in styles_element.Descendants() | |||||
| // let styleId = d.Attribute(XName.Get("styleId", DocX.w.NamespaceName)) | |||||
| // let type = d.Attribute(XName.Get("type", DocX.w.NamespaceName)) | |||||
| // where type != null && type.Value == "paragraph" && styleId != null && styleId.Value == id | |||||
| // select d | |||||
| // ).First(); | |||||
| // styles.Add(style); | |||||
| //} | |||||
| } | } | ||||
| } | } | ||||
| #endregion | #endregion | ||||
| /// </summary> | /// </summary> | ||||
| public Direction Direction | public Direction Direction | ||||
| { | { | ||||
| get { return Direction; } | |||||
| get | |||||
| { | |||||
| XElement pPr = GetOrCreate_pPr(); | |||||
| XElement bidi = pPr.Element(XName.Get("bidi", DocX.w.NamespaceName)); | |||||
| if (bidi == null) | |||||
| return Direction.LeftToRight; | |||||
| else | |||||
| return Direction.RightToLeft; | |||||
| } | |||||
| set | set | ||||
| { | { | ||||
| base.InsertPageBreakAfterSelf(); | base.InsertPageBreakAfterSelf(); | ||||
| } | } | ||||
| /// <summary> | |||||
| /// This function inserts a hyperlink into a Paragraph at a specified character index. | |||||
| /// </summary> | |||||
| /// <param name="index">The index to insert at.</param> | |||||
| /// <param name="h">The hyperlink to insert.</param> | |||||
| /// <returns>The Paragraph with the Hyperlink inserted at the specified index.</returns> | |||||
| /// <!-- | |||||
| /// This function was added by Brian Campbell aka chickendelicious on Jun 16 2010 | |||||
| /// Thank you Brian. | |||||
| /// --> | |||||
| public Paragraph InsertHyperlink(int index, Hyperlink h) | |||||
| { | |||||
| Run run = GetFirstRunEffectedByInsert(index); | |||||
| if (run == null) | |||||
| return AppendHyperlink(h); | |||||
| else | |||||
| { | |||||
| // The parent of this Run | |||||
| XElement parentElement = run.Xml.Parent; | |||||
| // Split this run at the point you want to insert | |||||
| XElement[] splitRun = Run.SplitRun(run, index); | |||||
| XElement link = h.Xml; | |||||
| // Replace the origional run | |||||
| run.Xml.ReplaceWith ( splitRun[0], link, splitRun[1] ); | |||||
| } | |||||
| // Rebuild the run lookup for this paragraph | |||||
| runLookup.Clear(); | |||||
| BuildRunLookup(Xml); | |||||
| HelperFunctions.RenumberIDs(Document); | |||||
| return this; | |||||
| } | |||||
| /// <summary> | /// <summary> | ||||
| /// Insert a Paragraph after this Paragraph, this Paragraph may have come from the same or another document. | /// Insert a Paragraph after this Paragraph, this Paragraph may have come from the same or another document. | ||||
| /// </summary> | /// </summary> | ||||
| } | } | ||||
| } | } | ||||
| DocX.RebuildParagraphs(Document); | |||||
| HelperFunctions.RebuildParagraphs(Document); | |||||
| } | } | ||||
| internal void BuildRunLookup(XElement p) | internal void BuildRunLookup(XElement p) | ||||
| // Rebuild the run lookup for this paragraph | // Rebuild the run lookup for this paragraph | ||||
| runLookup.Clear(); | runLookup.Clear(); | ||||
| BuildRunLookup(Xml); | BuildRunLookup(Xml); | ||||
| DocX.RenumberIDs(Document); | |||||
| HelperFunctions.RenumberIDs(Document); | |||||
| return picture; | return picture; | ||||
| } | } | ||||
| /// <param name="descr">The description of this Picture.</param> | /// <param name="descr">The description of this Picture.</param> | ||||
| static internal Picture CreatePicture(DocX document, string id, string name, string descr) | static internal Picture CreatePicture(DocX document, string id, string name, string descr) | ||||
| { | { | ||||
| PackagePart word_document = document.package.GetPart(new Uri("/word/document.xml", UriKind.Relative)); | |||||
| PackagePart part = document.package.GetPart(word_document.GetRelationship(id).TargetUri); | |||||
| PackagePart part = document.package.GetPart(document.mainPart.GetRelationship(id).TargetUri); | |||||
| int cx, cy; | int cx, cy; | ||||
| </drawing> | </drawing> | ||||
| ", cx, cy, id, name, descr)); | ", cx, cy, id, name, descr)); | ||||
| return new Picture(document, xml); | |||||
| return new Picture(document, xml, new Image(document, document.mainPart.GetRelationship(id))); | |||||
| } | } | ||||
| public Picture InsertPicture(int index, string imageID) | public Picture InsertPicture(int index, string imageID) | ||||
| /// <param name="trackChanges">Flag this insert as a change.</param> | /// <param name="trackChanges">Flag this insert as a change.</param> | ||||
| public void InsertText(string value, bool trackChanges) | public void InsertText(string value, bool trackChanges) | ||||
| { | { | ||||
| List<XElement> newRuns = DocX.FormatInput(value, null); | |||||
| List<XElement> newRuns = HelperFunctions.FormatInput(value, null); | |||||
| Xml.Add(newRuns); | Xml.Add(newRuns); | ||||
| runLookup.Clear(); | runLookup.Clear(); | ||||
| BuildRunLookup(Xml); | BuildRunLookup(Xml); | ||||
| DocX.RenumberIDs(Document); | |||||
| HelperFunctions.RenumberIDs(Document); | |||||
| } | } | ||||
| /// <summary> | /// <summary> | ||||
| /// <param name="formatting">The text formatting.</param> | /// <param name="formatting">The text formatting.</param> | ||||
| public void InsertText(string value, bool trackChanges, Formatting formatting) | public void InsertText(string value, bool trackChanges, Formatting formatting) | ||||
| { | { | ||||
| List<XElement> newRuns = DocX.FormatInput(value, formatting.Xml); | |||||
| List<XElement> newRuns = HelperFunctions.FormatInput(value, formatting.Xml); | |||||
| Xml.Add(newRuns); | Xml.Add(newRuns); | ||||
| runLookup.Clear(); | runLookup.Clear(); | ||||
| BuildRunLookup(Xml); | BuildRunLookup(Xml); | ||||
| DocX.RenumberIDs(Document); | |||||
| DocX.RebuildParagraphs(Document); | |||||
| HelperFunctions.RenumberIDs(Document); | |||||
| HelperFunctions.RebuildParagraphs(Document); | |||||
| } | } | ||||
| /// <summary> | /// <summary> | ||||
| { | { | ||||
| object insert; | object insert; | ||||
| if (formatting != null) | if (formatting != null) | ||||
| insert = DocX.FormatInput(value, formatting.Xml); | |||||
| insert = HelperFunctions.FormatInput(value, formatting.Xml); | |||||
| else | else | ||||
| insert = DocX.FormatInput(value, null); | |||||
| insert = HelperFunctions.FormatInput(value, null); | |||||
| if (trackChanges) | if (trackChanges) | ||||
| insert = CreateEdit(EditType.ins, insert_datetime, insert); | insert = CreateEdit(EditType.ins, insert_datetime, insert); | ||||
| { | { | ||||
| object newRuns; | object newRuns; | ||||
| if (formatting != null) | if (formatting != null) | ||||
| newRuns = DocX.FormatInput(value, formatting.Xml); | |||||
| newRuns = HelperFunctions.FormatInput(value, formatting.Xml); | |||||
| else | else | ||||
| newRuns = DocX.FormatInput(value, run.Xml.Element(XName.Get("rPr", DocX.w.NamespaceName))); | |||||
| newRuns = HelperFunctions.FormatInput(value, run.Xml.Element(XName.Get("rPr", DocX.w.NamespaceName))); | |||||
| // The parent of this Run | // The parent of this Run | ||||
| XElement parentElement = run.Xml.Parent; | XElement parentElement = run.Xml.Parent; | ||||
| // Rebuild the run lookup for this paragraph | // Rebuild the run lookup for this paragraph | ||||
| runLookup.Clear(); | runLookup.Clear(); | ||||
| BuildRunLookup(Xml); | BuildRunLookup(Xml); | ||||
| DocX.RenumberIDs(Document); | |||||
| HelperFunctions.RenumberIDs(Document); | |||||
| } | } | ||||
| /// <summary> | /// <summary> | ||||
| /// </example> | /// </example> | ||||
| public Paragraph Append(string text) | public Paragraph Append(string text) | ||||
| { | { | ||||
| List<XElement> newRuns = DocX.FormatInput(text, null); | |||||
| List<XElement> newRuns = HelperFunctions.FormatInput(text, null); | |||||
| Xml.Add(newRuns); | Xml.Add(newRuns); | ||||
| this.runs = Xml.Elements(XName.Get("r", DocX.w.NamespaceName)).Reverse().Take(newRuns.Count()).ToList(); | this.runs = Xml.Elements(XName.Get("r", DocX.w.NamespaceName)).Reverse().Take(newRuns.Count()).ToList(); | ||||
| /// </example> | /// </example> | ||||
| public Paragraph AppendHyperlink(Hyperlink h) | public Paragraph AppendHyperlink(Hyperlink h) | ||||
| { | { | ||||
| if(!h.hyperlink_rels.ContainsKey(mainPart)) | |||||
| { | |||||
| PackageRelationship pr = mainPart.CreateRelationship(h.Uri, TargetMode.External, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"); | |||||
| h.hyperlink_rels.Add(mainPart, pr); | |||||
| } | |||||
| PackageRelationship rel = h.hyperlink_rels[mainPart]; | |||||
| Xml.Add(h.Xml); | Xml.Add(h.Xml); | ||||
| Xml.Elements().Last().SetAttributeValue(DocX.r + "id", rel.Id); | |||||
| this.runs = Xml.Elements(XName.Get("r", DocX.w.NamespaceName)).Reverse().Take(h.Xml.Elements(XName.Get("r", DocX.w.NamespaceName)).Count()).ToList(); | this.runs = Xml.Elements(XName.Get("r", DocX.w.NamespaceName)).Reverse().Take(h.Xml.Elements(XName.Get("r", DocX.w.NamespaceName)).Count()).ToList(); | ||||
| BuildRunLookup(Xml); | BuildRunLookup(Xml); | ||||
| return this; | return this; | ||||
| } | |||||
| } | |||||
| /// <summary> | /// <summary> | ||||
| /// Add an image to a document, create a custom view of that image (picture) and then insert it into a Paragraph using append. | /// Add an image to a document, create a custom view of that image (picture) and then insert it into a Paragraph using append. | ||||
| /// </example> | /// </example> | ||||
| public Paragraph AppendPicture(Picture p) | public Paragraph AppendPicture(Picture p) | ||||
| { | { | ||||
| if (!p.picture_rels.ContainsKey(mainPart)) | |||||
| { | |||||
| PackageRelationship pr = mainPart.CreateRelationship(p.img.pr.TargetUri, TargetMode.Internal, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"); | |||||
| p.picture_rels.Add(mainPart, pr); | |||||
| } | |||||
| PackageRelationship rel = p.picture_rels[mainPart]; | |||||
| Xml.Add(p.Xml); | Xml.Add(p.Xml); | ||||
| XAttribute a_id = | |||||
| ( | |||||
| from e in Xml.Elements().Last().Descendants() | |||||
| where e.Name.LocalName.Equals("blip") | |||||
| select e.Attribute(XName.Get("embed", "http://schemas.openxmlformats.org/officeDocument/2006/relationships")) | |||||
| ).Single(); | |||||
| a_id.SetValue(rel.Id); | |||||
| this.runs = Xml.Elements(XName.Get("r", DocX.w.NamespaceName)).Reverse().Take(p.Xml.Elements(XName.Get("r", DocX.w.NamespaceName)).Count()).ToList(); | this.runs = Xml.Elements(XName.Get("r", DocX.w.NamespaceName)).Reverse().Take(p.Xml.Elements(XName.Get("r", DocX.w.NamespaceName)).Count()).ToList(); | ||||
| BuildRunLookup(Xml); | BuildRunLookup(Xml); | ||||
| // Rebuild the run lookup | // Rebuild the run lookup | ||||
| runLookup.Clear(); | runLookup.Clear(); | ||||
| BuildRunLookup(Xml); | BuildRunLookup(Xml); | ||||
| DocX.RenumberIDs(Document); | |||||
| HelperFunctions.RenumberIDs(Document); | |||||
| } | } | ||||
| /// </summary> | /// </summary> | ||||
| public class Picture: DocXElement | public class Picture: DocXElement | ||||
| { | { | ||||
| internal Dictionary<PackagePart, PackageRelationship> picture_rels; | |||||
| internal Image img; | |||||
| private string id; | private string id; | ||||
| private string name; | private string name; | ||||
| private string descr; | private string descr; | ||||
| /// Wraps an XElement as an Image | /// Wraps an XElement as an Image | ||||
| /// </summary> | /// </summary> | ||||
| /// <param name="i">The XElement i to wrap</param> | /// <param name="i">The XElement i to wrap</param> | ||||
| internal Picture(DocX document, XElement i):base(document, i) | |||||
| internal Picture(DocX document, XElement i, Image img):base(document, i) | |||||
| { | { | ||||
| picture_rels = new Dictionary<PackagePart, PackageRelationship>(); | |||||
| this.img = img; | |||||
| this.id = | this.id = | ||||
| ( | ( | ||||
| from e in Xml.Descendants() | from e in Xml.Descendants() | ||||
| where e.Name.LocalName.Equals("blip") | where e.Name.LocalName.Equals("blip") | ||||
| select e.Attribute(XName.Get("embed", "http://schemas.openxmlformats.org/officeDocument/2006/relationships")).Value | select e.Attribute(XName.Get("embed", "http://schemas.openxmlformats.org/officeDocument/2006/relationships")).Value | ||||
| ).Single(); | |||||
| ).Single(); | |||||
| this.name = | this.name = | ||||
| ( | ( |
| // You can specify all the values or you can default the Build and Revision Numbers | // You can specify all the values or you can default the Build and Revision Numbers | ||||
| // by using the '*' as shown below: | // by using the '*' as shown below: | ||||
| // [assembly: AssemblyVersion("1.0.*")] | // [assembly: AssemblyVersion("1.0.*")] | ||||
| [assembly: AssemblyVersion("1.0.0.9")] | |||||
| [assembly: AssemblyFileVersion("1.0.0.9")] | |||||
| [assembly: AssemblyVersion("1.0.0.10")] | |||||
| [assembly: AssemblyFileVersion("1.0.0.10")] |
| private List<Row> rows; | private List<Row> rows; | ||||
| private int rowCount, columnCount; | private int rowCount, columnCount; | ||||
| /// <summary> | |||||
| /// Returns a list of all Paragraphs inside this container. | |||||
| /// </summary> | |||||
| /// | |||||
| public virtual List<Paragraph> Paragraphs | |||||
| { | |||||
| get | |||||
| { | |||||
| List<Paragraph> paragraphs = new List<Paragraph>(); | |||||
| foreach (Row r in Rows) | |||||
| paragraphs.AddRange(r.Paragraphs); | |||||
| return paragraphs; | |||||
| } | |||||
| } | |||||
| /// <summary> | /// <summary> | ||||
| /// Returns a list of all Pictures in a Table. | /// Returns a list of all Pictures in a Table. | ||||
| /// </summary> | /// </summary> | ||||
| if (tableStyle == null) | if (tableStyle == null) | ||||
| { | { | ||||
| XDocument external_style_doc = DocX.DecompressXMLResource("Novacode.Resources.styles.xml.gz"); | |||||
| XDocument external_style_doc = HelperFunctions.DecompressXMLResource("Novacode.Resources.styles.xml.gz"); | |||||
| var styleElement = | var styleElement = | ||||
| ( | ( | ||||
| /// foreach (Cell c in row.Cells) | /// foreach (Cell c in row.Cells) | ||||
| /// { | /// { | ||||
| /// // Set the text of each new cell to "Hello". | /// // Set the text of each new cell to "Hello". | ||||
| /// c.Paragraph.InsertText("Hello", false); | |||||
| /// c.Paragraphs[0].InsertText("Hello", false); | |||||
| /// } | /// } | ||||
| /// | /// | ||||
| /// // Save the document to a new file. | /// // Save the document to a new file. | ||||
| /// // The cell in this row that belongs to the new coloumn. | /// // The cell in this row that belongs to the new coloumn. | ||||
| /// Cell cell = row.Cells[table.ColumnCount - 1]; | /// Cell cell = row.Cells[table.ColumnCount - 1]; | ||||
| /// | /// | ||||
| /// // The Paragraph that this cell houses. | |||||
| /// Paragraph p = cell.Paragraph; | |||||
| /// // The first Paragraph that this cell houses. | |||||
| /// Paragraph p = cell.Paragraphs[0]; | |||||
| /// | /// | ||||
| /// // Insert this rows index. | /// // Insert this rows index. | ||||
| /// p.InsertText(i.ToString(), false); | /// p.InsertText(i.ToString(), false); | ||||
| /// foreach (Cell c in row.Cells) | /// foreach (Cell c in row.Cells) | ||||
| /// { | /// { | ||||
| /// // Set the text of each new cell to "Hello". | /// // Set the text of each new cell to "Hello". | ||||
| /// c.Paragraph.InsertText("Hello", false); | |||||
| /// c.Paragraphs[0].InsertText("Hello", false); | |||||
| /// } | /// } | ||||
| /// | /// | ||||
| /// // Save the document to a new file. | /// // Save the document to a new file. | ||||
| /// // The cell in this row that belongs to the new coloumn. | /// // The cell in this row that belongs to the new coloumn. | ||||
| /// Cell cell = row.Cells[table.ColumnCount - 1]; | /// Cell cell = row.Cells[table.ColumnCount - 1]; | ||||
| /// | /// | ||||
| /// // The Paragraph that this cell houses. | |||||
| /// Paragraph p = cell.Paragraph; | |||||
| /// // The first Paragraph that this cell houses. | |||||
| /// Paragraph p = cell.Paragraphs[0]; | |||||
| /// | /// | ||||
| /// // Insert this rows index. | /// // Insert this rows index. | ||||
| /// p.InsertText(i.ToString(), false); | /// p.InsertText(i.ToString(), false); | ||||
| /// <summary> | /// <summary> | ||||
| /// Represents a single row in a Table. | /// Represents a single row in a Table. | ||||
| /// </summary> | /// </summary> | ||||
| public class Row:DocXElement | |||||
| public class Row : Container | |||||
| { | { | ||||
| private List<Cell> cells; | |||||
| /// <summary> | /// <summary> | ||||
| /// A list of Cells in this Row. | /// A list of Cells in this Row. | ||||
| /// </summary> | /// </summary> | ||||
| public List<Cell> Cells { get { return cells; } } | |||||
| internal Row(DocX document, XElement xml):base(document, xml) | |||||
| { | |||||
| cells = (from c in xml.Elements(XName.Get("tc", DocX.w.NamespaceName)) | |||||
| select new Cell(document, c)).ToList(); | |||||
| } | |||||
| /// <summary> | |||||
| /// Returns a list of all Pictures in a Row. | |||||
| /// </summary> | |||||
| /// <example> | |||||
| /// Returns a list of all Pictures in a Row. | |||||
| /// <code> | |||||
| /// // Create a document. | |||||
| /// using (DocX document = DocX.Load(@"Test.docx")) | |||||
| /// { | |||||
| /// // Get the first Table in a document. | |||||
| /// Table t = document.Tables[0]; | |||||
| /// | |||||
| /// // Get the first Row in a Table. | |||||
| /// Row r = t.Rows[0]; | |||||
| /// | |||||
| /// // Get all of the Pictures in this Row. | |||||
| /// List<Picture> pictures = r.Pictures; | |||||
| /// | |||||
| /// // Save this document. | |||||
| /// document.Save(); | |||||
| /// } | |||||
| /// </code> | |||||
| /// </example> | |||||
| public List<Picture> Pictures | |||||
| { | |||||
| get | |||||
| public List<Cell> Cells | |||||
| { | |||||
| get | |||||
| { | { | ||||
| List<Picture> pictures = new List<Picture>(); | |||||
| foreach (Cell c in Cells) | |||||
| pictures.AddRange(c.Pictures); | |||||
| return pictures; | |||||
| } | |||||
| } | |||||
| /// <summary> | |||||
| /// Get all of the Hyperlinks in this Row. | |||||
| /// </summary> | |||||
| /// <example> | |||||
| /// Get all of the Hyperlinks in this Row. | |||||
| /// <code> | |||||
| /// // Create a document. | |||||
| /// using (DocX document = DocX.Load(@"Test.docx")) | |||||
| /// { | |||||
| /// // Get the first Table in this document. | |||||
| /// Table t = document.Tables[0]; | |||||
| /// | |||||
| /// // Get the first Row in this Table. | |||||
| /// Row r = t.Rows[0]; | |||||
| /// | |||||
| /// // Get a list of all Hyperlinks in this Row. | |||||
| /// List<Hyperlink> hyperlinks = r.Hyperlinks; | |||||
| /// | |||||
| /// // Save this document. | |||||
| /// document.Save(); | |||||
| /// } | |||||
| /// </code> | |||||
| /// </example> | |||||
| public List<Hyperlink> Hyperlinks | |||||
| { | |||||
| get | |||||
| { | |||||
| List<Hyperlink> hyperlinks = new List<Hyperlink>(); | |||||
| foreach (Cell c in Cells) | |||||
| hyperlinks.AddRange(c.Hyperlinks); | |||||
| List<Cell> cells = | |||||
| ( | |||||
| from c in Xml.Elements(XName.Get("tc", DocX.w.NamespaceName)) | |||||
| select new Cell(Document, c) | |||||
| ).ToList(); | |||||
| return hyperlinks; | |||||
| } | |||||
| return cells; | |||||
| } | |||||
| } | } | ||||
| /// <summary> | |||||
| /// Set the content direction of a single Row in a Table. | |||||
| /// </summary> | |||||
| /// <param name="direction">The direction either (LeftToRight or RightToLeft).</param> | |||||
| /// <example> | |||||
| /// Set the content direction of a single Row in a Table. | |||||
| /// <code> | |||||
| /// // Load a document. | |||||
| /// using (DocX document = DocX.Load(@"Test.docx")) | |||||
| /// { | |||||
| /// // Get the first Table from a document. | |||||
| /// Table t = document.Tables[0]; | |||||
| /// | |||||
| /// // Get the first row from this Table. | |||||
| /// Row r = t.Rows[0]; | |||||
| /// | |||||
| /// // Set the content direction of this Row to RightToLeft. | |||||
| /// r.SetDirection(Direction.RightToLeft); | |||||
| /// | |||||
| /// // Save all changes made to this document. | |||||
| /// document.Save(); | |||||
| ///} | |||||
| /// </code> | |||||
| /// </example> | |||||
| public void SetDirection(Direction direction) | |||||
| internal Row(DocX document, XElement xml):base(document, xml) | |||||
| { | { | ||||
| foreach (Cell c in Cells) | |||||
| c.SetDirection(direction); | |||||
| } | } | ||||
| /// <summary> | /// <summary> | ||||
| int gridSpanSum = 0; | int gridSpanSum = 0; | ||||
| // Foreach each Cell between startIndex and endIndex inclusive. | // Foreach each Cell between startIndex and endIndex inclusive. | ||||
| foreach (Cell c in cells.Where((z, i) => i > startIndex && i <= endIndex)) | |||||
| foreach (Cell c in Cells.Where((z, i) => i > startIndex && i <= endIndex)) | |||||
| { | { | ||||
| XElement tcPr = c.Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName)); | XElement tcPr = c.Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName)); | ||||
| if (tcPr != null) | if (tcPr != null) | ||||
| } | } | ||||
| // Add this cells Pragraph to the merge start Cell. | // Add this cells Pragraph to the merge start Cell. | ||||
| cells[startIndex].Xml.Add(c.Xml.Elements(XName.Get("p", DocX.w.NamespaceName))); | |||||
| Cells[startIndex].Xml.Add(c.Xml.Elements(XName.Get("p", DocX.w.NamespaceName))); | |||||
| // Remove this Cell. | // Remove this Cell. | ||||
| c.Xml.Remove(); | c.Xml.Remove(); | ||||
| * Get the tcPr (table cell properties) element for the first cell in this merge, | * Get the tcPr (table cell properties) element for the first cell in this merge, | ||||
| * null will be returned if no such element exists. | * null will be returned if no such element exists. | ||||
| */ | */ | ||||
| XElement start_tcPr = cells[startIndex].Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName)); | |||||
| XElement start_tcPr = Cells[startIndex].Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName)); | |||||
| if (start_tcPr == null) | if (start_tcPr == null) | ||||
| { | { | ||||
| cells[startIndex].Xml.SetElementValue(XName.Get("tcPr", DocX.w.NamespaceName), string.Empty); | |||||
| start_tcPr = cells[startIndex].Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName)); | |||||
| Cells[startIndex].Xml.SetElementValue(XName.Get("tcPr", DocX.w.NamespaceName), string.Empty); | |||||
| start_tcPr = Cells[startIndex].Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName)); | |||||
| } | } | ||||
| /* | /* | ||||
| // Set the val attribute to the number of merged cells. | // Set the val attribute to the number of merged cells. | ||||
| start_gridSpan.SetAttributeValue(XName.Get("val", DocX.w.NamespaceName), (gridSpanSum + (endIndex - startIndex + 1)).ToString()); | start_gridSpan.SetAttributeValue(XName.Get("val", DocX.w.NamespaceName), (gridSpanSum + (endIndex - startIndex + 1)).ToString()); | ||||
| // Rebuild the cells collection. | |||||
| cells = | |||||
| ( | |||||
| from c in Xml.Elements(XName.Get("tc", DocX.w.NamespaceName)) | |||||
| select new Cell(Document, c) | |||||
| ).ToList(); | |||||
| } | } | ||||
| } | } | ||||
| public class Cell:DocXElement | |||||
| public class Cell:Container | |||||
| { | { | ||||
| private List<Paragraph> paragraphs; | |||||
| public List<Paragraph> Paragraphs | |||||
| { | |||||
| get { return paragraphs; } | |||||
| set { paragraphs = value; } | |||||
| } | |||||
| internal Cell(DocX document, XElement xml):base(document, xml) | internal Cell(DocX document, XElement xml):base(document, xml) | ||||
| { | { | ||||
| paragraphs = xml.Elements(XName.Get("p", DocX.w.NamespaceName)).Select(p => new Paragraph(document, p, 0)).ToList(); | |||||
| } | |||||
| /// <summary> | |||||
| /// Returns a list of all Pictures in a Cell. | |||||
| /// </summary> | |||||
| /// <example> | |||||
| /// Returns a list of all Pictures in a Cell. | |||||
| /// <code> | |||||
| /// // Create a document. | |||||
| /// using (DocX document = DocX.Load(@"Test.docx")) | |||||
| /// { | |||||
| /// // Get the first Table in a document. | |||||
| /// Table t = document.Tables[0]; | |||||
| /// | |||||
| /// // Get the first Row in a Table. | |||||
| /// Row r = t.Rows[0]; | |||||
| /// | |||||
| /// // Get the first Cell in a Row. | |||||
| /// Cell c = r.Cells[0]; | |||||
| /// | |||||
| /// // Get all of the Pictures in this Cell. | |||||
| /// List<Picture> pictures = c.Pictures; | |||||
| /// | |||||
| /// // Save this document. | |||||
| /// document.Save(); | |||||
| /// } | |||||
| /// </code> | |||||
| /// </example> | |||||
| public List<Picture> Pictures | |||||
| { | |||||
| get | |||||
| { | |||||
| List<Picture> pictures = new List<Picture>(); | |||||
| foreach (Paragraph p in Paragraphs) | |||||
| pictures.AddRange(p.Pictures); | |||||
| return pictures; | |||||
| } | |||||
| } | |||||
| /// <summary> | |||||
| /// Get all of the Hyperlinks in this Cell. | |||||
| /// </summary> | |||||
| /// <example> | |||||
| /// Get all of the Hyperlinks in this Cell. | |||||
| /// <code> | |||||
| /// // Create a document. | |||||
| /// using (DocX document = DocX.Load(@"Test.docx")) | |||||
| /// { | |||||
| /// // Get the first Table in this document. | |||||
| /// Table t = document.Tables[0]; | |||||
| /// | |||||
| /// // Get the first Row in this Table. | |||||
| /// Row r = t.Rows[0]; | |||||
| /// | |||||
| /// // Get the first Cell in this Row. | |||||
| /// Cell c = r.Cells[0]; | |||||
| /// | |||||
| /// // Get a list of all Hyperlinks in this Cell. | |||||
| /// List<Hyperlink> hyperlinks = c.Hyperlinks; | |||||
| /// | |||||
| /// // Save this document. | |||||
| /// document.Save(); | |||||
| /// } | |||||
| /// </code> | |||||
| /// </example> | |||||
| public List<Hyperlink> Hyperlinks | |||||
| { | |||||
| get | |||||
| { | |||||
| List<Hyperlink> hyperlinks = new List<Hyperlink>(); | |||||
| foreach (Paragraph p in Paragraphs) | |||||
| hyperlinks.AddRange(p.Hyperlinks); | |||||
| return hyperlinks; | |||||
| } | |||||
| } | |||||
| /// <summary> | |||||
| /// Set the content direction of a single Cell in a Table. | |||||
| /// </summary> | |||||
| /// <param name="direction">The direction either (LeftToRight or RightToLeft).</param> | |||||
| /// <example> | |||||
| /// Set the content direction of a single Cell in a Table. | |||||
| /// <code> | |||||
| /// // Load a document. | |||||
| /// using (DocX document = DocX.Load(@"Test.docx")) | |||||
| /// { | |||||
| /// // Get the first Table from a document. | |||||
| /// Table t = document.Tables[0]; | |||||
| /// | |||||
| /// // Get the first row from this Table. | |||||
| /// Row r = t.Rows[0]; | |||||
| /// | |||||
| /// // Get the first cell from this Row. | |||||
| /// Cell c = r.Cells[1]; | |||||
| /// | |||||
| /// // Set the content direction of this Cell to RightToLeft. | |||||
| /// c.SetDirection(Direction.RightToLeft); | |||||
| /// | |||||
| /// // Save all changes made to this document. | |||||
| /// document.Save(); | |||||
| ///} | |||||
| /// </code> | |||||
| /// </example> | |||||
| public void SetDirection(Direction direction) | |||||
| { | |||||
| foreach (Paragraph p in Paragraphs) | |||||
| p.Direction = direction; | |||||
| } | } | ||||
| public Color Shading | public Color Shading |
| XElement newlyInserted = Xml.ElementsBeforeSelf().First(); | XElement newlyInserted = Xml.ElementsBeforeSelf().First(); | ||||
| p.Xml = newlyInserted; | p.Xml = newlyInserted; | ||||
| DocX.RebuildParagraphs(Document); | |||||
| HelperFunctions.RebuildParagraphs(Document); | |||||
| return p; | return p; | ||||
| } | } | ||||
| XElement newlyInserted = Xml.ElementsAfterSelf().First(); | XElement newlyInserted = Xml.ElementsAfterSelf().First(); | ||||
| p.Xml = newlyInserted; | p.Xml = newlyInserted; | ||||
| DocX.RebuildParagraphs(Document); | |||||
| HelperFunctions.RebuildParagraphs(Document); | |||||
| return p; | return p; | ||||
| } | } | ||||
| { | { | ||||
| XElement newParagraph = new XElement | XElement newParagraph = new XElement | ||||
| ( | ( | ||||
| XName.Get("p", DocX.w.NamespaceName), new XElement(XName.Get("pPr", DocX.w.NamespaceName)), DocX.FormatInput(text, formatting.Xml) | |||||
| XName.Get("p", DocX.w.NamespaceName), new XElement(XName.Get("pPr", DocX.w.NamespaceName)), HelperFunctions.FormatInput(text, formatting.Xml) | |||||
| ); | ); | ||||
| if (trackChanges) | if (trackChanges) | ||||
| XElement newlyInserted = Xml.ElementsBeforeSelf().First(); | XElement newlyInserted = Xml.ElementsBeforeSelf().First(); | ||||
| Paragraph p = new Paragraph(Document, newlyInserted, -1); | Paragraph p = new Paragraph(Document, newlyInserted, -1); | ||||
| DocX.RebuildParagraphs(Document); | |||||
| HelperFunctions.RebuildParagraphs(Document); | |||||
| return p; | return p; | ||||
| } | } | ||||
| { | { | ||||
| XElement newParagraph = new XElement | XElement newParagraph = new XElement | ||||
| ( | ( | ||||
| XName.Get("p", DocX.w.NamespaceName), new XElement(XName.Get("pPr", DocX.w.NamespaceName)), DocX.FormatInput(text, formatting.Xml) | |||||
| XName.Get("p", DocX.w.NamespaceName), new XElement(XName.Get("pPr", DocX.w.NamespaceName)), HelperFunctions.FormatInput(text, formatting.Xml) | |||||
| ); | ); | ||||
| if (trackChanges) | if (trackChanges) | ||||
| XElement newlyInserted = Xml.ElementsAfterSelf().First(); | XElement newlyInserted = Xml.ElementsAfterSelf().First(); | ||||
| Paragraph p = new Paragraph(Document, newlyInserted, -1); | Paragraph p = new Paragraph(Document, newlyInserted, -1); | ||||
| DocX.RebuildParagraphs(Document); | |||||
| HelperFunctions.RebuildParagraphs(Document); | |||||
| return p; | return p; | ||||
| } | } | ||||
| public virtual Table InsertTableAfterSelf(int rowCount, int coloumnCount) | public virtual Table InsertTableAfterSelf(int rowCount, int coloumnCount) | ||||
| { | { | ||||
| XElement newTable = DocX.CreateTable(rowCount, coloumnCount); | |||||
| XElement newTable = HelperFunctions.CreateTable(rowCount, coloumnCount); | |||||
| Xml.AddAfterSelf(newTable); | Xml.AddAfterSelf(newTable); | ||||
| XElement newlyInserted = Xml.ElementsAfterSelf().First(); | XElement newlyInserted = Xml.ElementsAfterSelf().First(); | ||||
| ////DocX.RebuildTables(Document); | ////DocX.RebuildTables(Document); | ||||
| DocX.RebuildParagraphs(Document); | |||||
| HelperFunctions.RebuildParagraphs(Document); | |||||
| return new Table(Document, newlyInserted); | return new Table(Document, newlyInserted); | ||||
| } | } | ||||
| t.Xml = newlyInserted; | t.Xml = newlyInserted; | ||||
| //DocX.RebuildTables(Document); | //DocX.RebuildTables(Document); | ||||
| DocX.RebuildParagraphs(Document); | |||||
| HelperFunctions.RebuildParagraphs(Document); | |||||
| return t; | return t; | ||||
| } | } | ||||
| public virtual Table InsertTableBeforeSelf(int rowCount, int coloumnCount) | public virtual Table InsertTableBeforeSelf(int rowCount, int coloumnCount) | ||||
| { | { | ||||
| XElement newTable = DocX.CreateTable(rowCount, coloumnCount); | |||||
| XElement newTable = HelperFunctions.CreateTable(rowCount, coloumnCount); | |||||
| Xml.AddBeforeSelf(newTable); | Xml.AddBeforeSelf(newTable); | ||||
| XElement newlyInserted = Xml.ElementsBeforeSelf().First(); | XElement newlyInserted = Xml.ElementsBeforeSelf().First(); | ||||
| //DocX.RebuildTables(Document); | //DocX.RebuildTables(Document); | ||||
| DocX.RebuildParagraphs(Document); | |||||
| HelperFunctions.RebuildParagraphs(Document); | |||||
| return new Table(Document, newlyInserted); | return new Table(Document, newlyInserted); | ||||
| } | } | ||||
| t.Xml = newlyInserted; | t.Xml = newlyInserted; | ||||
| //DocX.RebuildTables(Document); | //DocX.RebuildTables(Document); | ||||
| DocX.RebuildParagraphs(Document); | |||||
| HelperFunctions.RebuildParagraphs(Document); | |||||
| return t; | return t; | ||||
| } | } |
| namespace Novacode | namespace Novacode | ||||
| { | { | ||||
| public enum XmlDocument { Main, HeaderOdd, HeaderEven, HeaderFirst, FooterOdd, FooterEven, FooterFirst }; | |||||
| public enum MatchFormattingOptions { ExactMatch, SubsetMatch}; | public enum MatchFormattingOptions { ExactMatch, SubsetMatch}; | ||||
| public enum Script { superscript, subscript, none } | public enum Script { superscript, subscript, none } | ||||
| public enum Highlight { yellow, green, cyan, magenta, blue, red, darkBlue, darkCyan, darkGreen, darkMagenta, darkRed, darkYellow, darkGray, lightGray, black, none }; | public enum Highlight { yellow, green, cyan, magenta, blue, red, darkBlue, darkCyan, darkGreen, darkMagenta, darkRed, darkYellow, darkGray, lightGray, black, none }; |