This one is a performance boost for cases where docs have lots of paragraphs inserted (through tables or whatever)... In the case that I found the issue, I was creating a report that added a lot of plain text paragraphs followed by lots of tables.. (creating a 40 page doc) (the fix is to avoid using the Paragraphs collection to get the one that was just added.. it fixes the reference to the "mainPart" so things like images that are added still work... ) All unit tests pass after this test (did have to fix some case issues with the one that does text replacements though) Includes: -fix for default column widths (also works when column widths are not specified) - issue that was breaking tables with more than 14 cols -New table method to set the widths for variable row tables... you can call Table.SetWidths(float [] yourWidthsInPixels) then for each row added those cols will have that width applied.. can help clean up some code.. also caches the column count for performance.. - Change for DocX that turns on zip compression for the parts of the doc (created docs are as small as re-saved versions from word now)master
| @@ -95,9 +95,9 @@ namespace Novacode | |||
| return true; | |||
| } | |||
| ++i; | |||
| } | |||
| return false; | |||
| } | |||
| @@ -170,32 +170,32 @@ namespace Novacode | |||
| //find num node in numbering | |||
| var numNodes = Document.numbering.Descendants().Where(n => n.Name.LocalName == "num"); | |||
| XElement numNode = numNodes.FirstOrDefault(node => node.Attribute(DocX.w + "numId").Value.Equals(numIdValue)); | |||
| if (numNode != null) | |||
| { | |||
| //Get abstractNumId node and its value from numNode | |||
| var abstractNumIdNode = numNode.Descendants().First(n => n.Name.LocalName == "abstractNumId"); | |||
| var abstractNumNodeValue = abstractNumIdNode.Attribute(DocX.w + "val").Value; | |||
| var abstractNumNodes = Document.numbering.Descendants().Where(n => n.Name.LocalName == "abstractNum"); | |||
| XElement abstractNumNode = | |||
| abstractNumNodes.FirstOrDefault(node => node.Attribute(DocX.w + "abstractNumId").Value.Equals(abstractNumNodeValue)); | |||
| //Find lvl node | |||
| var lvlNodes = abstractNumNode.Descendants().Where(n => n.Name.LocalName == "lvl"); | |||
| XElement lvlNode = null; | |||
| foreach (XElement node in lvlNodes) | |||
| { | |||
| if (node.Attribute(DocX.w + "ilvl").Value.Equals(ilvlValue)) | |||
| { | |||
| lvlNode = node; | |||
| break; | |||
| } | |||
| } | |||
| var numFmtNode = lvlNode.Descendants().First(n => n.Name.LocalName == "numFmt"); | |||
| p.ListItemType = GetListItemType(numFmtNode.Attribute(DocX.w + "val").Value); | |||
| } | |||
| if (numNode != null) | |||
| { | |||
| //Get abstractNumId node and its value from numNode | |||
| var abstractNumIdNode = numNode.Descendants().First(n => n.Name.LocalName == "abstractNumId"); | |||
| var abstractNumNodeValue = abstractNumIdNode.Attribute(DocX.w + "val").Value; | |||
| var abstractNumNodes = Document.numbering.Descendants().Where(n => n.Name.LocalName == "abstractNum"); | |||
| XElement abstractNumNode = | |||
| abstractNumNodes.FirstOrDefault(node => node.Attribute(DocX.w + "abstractNumId").Value.Equals(abstractNumNodeValue)); | |||
| //Find lvl node | |||
| var lvlNodes = abstractNumNode.Descendants().Where(n => n.Name.LocalName == "lvl"); | |||
| XElement lvlNode = null; | |||
| foreach (XElement node in lvlNodes) | |||
| { | |||
| if (node.Attribute(DocX.w + "ilvl").Value.Equals(ilvlValue)) | |||
| { | |||
| lvlNode = node; | |||
| break; | |||
| } | |||
| } | |||
| var numFmtNode = lvlNode.Descendants().First(n => n.Name.LocalName == "numFmt"); | |||
| p.ListItemType = GetListItemType(numFmtNode.Attribute(DocX.w + "val").Value); | |||
| } | |||
| } | |||
| @@ -499,7 +499,7 @@ namespace Novacode | |||
| if (Paragraphs.Any(p => p.ValidateBookmark(bookmarkName))) return new string[0]; | |||
| nonMatching.Add(bookmarkName); | |||
| } | |||
| return nonMatching.ToArray(); | |||
| } | |||
| @@ -771,10 +771,33 @@ namespace Novacode | |||
| if (trackChanges) | |||
| newParagraph = HelperFunctions.CreateEdit(EditType.ins, DateTime.Now, newParagraph); | |||
| Xml.Add(newParagraph); | |||
| var paragraphAdded = new Paragraph(Document, newParagraph, 0); | |||
| if (this is Cell) | |||
| { | |||
| var cell = this as Cell; | |||
| paragraphAdded.PackagePart = cell.mainPart; | |||
| } | |||
| else if (this is DocX) | |||
| { | |||
| paragraphAdded.PackagePart = Document.mainPart; | |||
| } | |||
| else if (this is Footer) | |||
| { | |||
| var f = this as Footer; | |||
| paragraphAdded.mainPart = f.mainPart; | |||
| } | |||
| else if (this is Header) | |||
| { | |||
| var h = this as Header; | |||
| paragraphAdded.mainPart = h.mainPart; | |||
| } | |||
| else | |||
| { | |||
| Console.WriteLine("No idea what we are {0}", this); | |||
| paragraphAdded.PackagePart = Document.mainPart; | |||
| } | |||
| var paragraphAdded = Paragraphs.Last(); | |||
| GetParent(paragraphAdded); | |||
| @@ -867,7 +890,7 @@ namespace Novacode | |||
| { | |||
| foreach (var item in list.Items) | |||
| { | |||
| // item.Font(System.Drawing.FontFamily fontFamily) | |||
| // item.Font(System.Drawing.FontFamily fontFamily) | |||
| Xml.Add(item.Xml); | |||
| } | |||
| @@ -882,13 +882,13 @@ namespace Novacode | |||
| return HelperFunctions.GetText(Xml); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Get the text of each footnote from this document | |||
| /// </summary> | |||
| public IEnumerable<string> FootnotesText | |||
| { | |||
| get | |||
| { | |||
| /// <summary> | |||
| /// Get the text of each footnote from this document | |||
| /// </summary> | |||
| public IEnumerable<string> FootnotesText | |||
| { | |||
| get | |||
| { | |||
| foreach (XElement footnote in footnotes.Root.Elements(w + "footnote")) | |||
| { | |||
| yield return HelperFunctions.GetText(footnote); | |||
| @@ -1043,7 +1043,7 @@ namespace Novacode | |||
| merge_footnotes(remote_pp, local_pp, remote_mainDoc, remote_document, remote_footnotes); | |||
| remote_footnotes = footnotes; | |||
| break; | |||
| case "application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml": | |||
| merge_endnotes(remote_pp, local_pp, remote_mainDoc, remote_document, remote_endnotes); | |||
| remote_endnotes = endnotes; | |||
| @@ -1201,9 +1201,9 @@ namespace Novacode | |||
| // In my testing I have found cases of Images inside documents that are not referenced | |||
| var remote_rel = remote_document.mainPart.GetRelationships().Where(r => r.TargetUri.OriginalString.Equals(remote_pp.Uri.OriginalString.Replace("/word/", ""))).FirstOrDefault(); | |||
| if (remote_rel == null) { | |||
| remote_rel = remote_document.mainPart.GetRelationships().Where(r => r.TargetUri.OriginalString.Equals(remote_pp.Uri.OriginalString)).FirstOrDefault(); | |||
| if (remote_rel == null) | |||
| return; | |||
| remote_rel = remote_document.mainPart.GetRelationships().Where(r => r.TargetUri.OriginalString.Equals(remote_pp.Uri.OriginalString)).FirstOrDefault(); | |||
| if (remote_rel == null) | |||
| return; | |||
| } | |||
| String remote_Id = remote_rel.Id; | |||
| @@ -1265,7 +1265,7 @@ namespace Novacode | |||
| if (!new_uri.StartsWith("/")) | |||
| new_uri = "/" + new_uri; | |||
| PackagePart new_pp = package.CreatePart(new Uri(new_uri, UriKind.Relative), remote_pp.ContentType); | |||
| PackagePart new_pp = package.CreatePart(new Uri(new_uri, UriKind.Relative), remote_pp.ContentType, CompressionOption.Normal); | |||
| using (Stream s_read = remote_pp.GetStream()) | |||
| { | |||
| @@ -1299,30 +1299,30 @@ namespace Novacode | |||
| } | |||
| if (!defRelId.Success) | |||
| { | |||
| // Replace all instances of remote_Id in the local document with local_Id | |||
| var elems_local = mainDoc.Descendants(XName.Get("blip", DocX.a.NamespaceName)); | |||
| foreach (var elem in elems_local) | |||
| { | |||
| XAttribute embed = elem.Attribute(XName.Get("embed", DocX.r.NamespaceName)); | |||
| if (embed != null && embed.Value == remote_Id) | |||
| { | |||
| embed.SetValue(new_Id); | |||
| } | |||
| } | |||
| // Replace all instances of remote_Id in the local document with local_Id | |||
| var v_elems_local = mainDoc.Descendants(XName.Get("imagedata", DocX.v.NamespaceName)); | |||
| foreach (var elem in v_elems_local) | |||
| { | |||
| XAttribute id = elem.Attribute(XName.Get("id", DocX.r.NamespaceName)); | |||
| if (id != null && id.Value == remote_Id) | |||
| { | |||
| id.SetValue(new_Id); | |||
| } | |||
| } | |||
| } | |||
| { | |||
| // Replace all instances of remote_Id in the local document with local_Id | |||
| var elems_local = mainDoc.Descendants(XName.Get("blip", DocX.a.NamespaceName)); | |||
| foreach (var elem in elems_local) | |||
| { | |||
| XAttribute embed = elem.Attribute(XName.Get("embed", DocX.r.NamespaceName)); | |||
| if (embed != null && embed.Value == remote_Id) | |||
| { | |||
| embed.SetValue(new_Id); | |||
| } | |||
| } | |||
| // Replace all instances of remote_Id in the local document with local_Id | |||
| var v_elems_local = mainDoc.Descendants(XName.Get("imagedata", DocX.v.NamespaceName)); | |||
| foreach (var elem in v_elems_local) | |||
| { | |||
| XAttribute id = elem.Attribute(XName.Get("id", DocX.r.NamespaceName)); | |||
| if (id != null && id.Value == remote_Id) | |||
| { | |||
| id.SetValue(new_Id); | |||
| } | |||
| } | |||
| } | |||
| // Replace all instances of remote_Id in the local document with local_Id (for shapes as well) | |||
| @@ -1547,10 +1547,10 @@ namespace Novacode | |||
| // Checking whether there were more than 0 elements, helped me get rid of exceptions thrown while using InsertDocument | |||
| if (numbering.Root.Elements(XName.Get("abstractNum", DocX.w.NamespaceName)).Count() > 0) | |||
| numbering.Root.Elements(XName.Get("abstractNum", DocX.w.NamespaceName)).Last().AddAfterSelf(remote_abstractNums); | |||
| numbering.Root.Elements(XName.Get("abstractNum", DocX.w.NamespaceName)).Last().AddAfterSelf(remote_abstractNums); | |||
| if (numbering.Root.Elements(XName.Get("num", DocX.w.NamespaceName)).Count() > 0) | |||
| numbering.Root.Elements(XName.Get("num", DocX.w.NamespaceName)).Last().AddAfterSelf(remote_nums); | |||
| numbering.Root.Elements(XName.Get("num", DocX.w.NamespaceName)).Last().AddAfterSelf(remote_nums); | |||
| } | |||
| private void merge_fonts(PackagePart remote_pp, PackagePart local_pp, XDocument remote_mainDoc, DocX remote) | |||
| @@ -1723,7 +1723,7 @@ namespace Novacode | |||
| } | |||
| } | |||
| // Replace all instances of remote_Id in the local document with local_Id (for shapes as well) | |||
| // Replace all instances of remote_Id in the local document with local_Id (for shapes as well) | |||
| var v_elems = remote_mainDoc.Descendants(XName.Get("imagedata", DocX.v.NamespaceName)); | |||
| foreach (var elem in v_elems) | |||
| { | |||
| @@ -1740,7 +1740,7 @@ namespace Novacode | |||
| protected PackagePart clonePackagePart(PackagePart pp) | |||
| { | |||
| PackagePart new_pp = package.CreatePart(pp.Uri, pp.ContentType); | |||
| PackagePart new_pp = package.CreatePart(pp.Uri, pp.ContentType, CompressionOption.Normal); | |||
| using (Stream s_read = pp.GetStream()) | |||
| { | |||
| @@ -1862,7 +1862,7 @@ namespace Novacode | |||
| /// </returns> | |||
| public List AddListItem(List list, string listText, int level = 0, ListItemType listType = ListItemType.Numbered, int? startNumber = null, bool trackChanges = false, bool continueNumbering = false) | |||
| { | |||
| if(startNumber.HasValue && continueNumbering) throw new InvalidOperationException("Cannot specify a start number and at the same time continue numbering from another list"); | |||
| if (startNumber.HasValue && continueNumbering) throw new InvalidOperationException("Cannot specify a start number and at the same time continue numbering from another list"); | |||
| var listToReturn = HelperFunctions.CreateItemInList(list, listText, level, listType, startNumber, trackChanges, continueNumbering); | |||
| var lastItem = listToReturn.Items.LastOrDefault(); | |||
| if (lastItem != null) | |||
| @@ -2206,11 +2206,11 @@ namespace Novacode | |||
| PackagePart mainDocumentPart; | |||
| if (documentType == DocumentTypes.Document) | |||
| { | |||
| mainDocumentPart = package.CreatePart(new Uri("/word/document.xml", UriKind.Relative), "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"); | |||
| mainDocumentPart = package.CreatePart(new Uri("/word/document.xml", UriKind.Relative), "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml", CompressionOption.Normal); | |||
| } | |||
| else | |||
| { | |||
| mainDocumentPart = package.CreatePart(new Uri("/word/document.xml", UriKind.Relative), "application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml"); | |||
| mainDocumentPart = package.CreatePart(new Uri("/word/document.xml", UriKind.Relative), "application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml", CompressionOption.Normal); | |||
| } | |||
| package.CreateRelationship(mainDocumentPart.Uri, TargetMode.Internal, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"); | |||
| @@ -2276,7 +2276,7 @@ namespace Novacode | |||
| if (!document.paragraphLookup.ContainsKey(paragraph.endIndex)) | |||
| document.paragraphLookup.Add(paragraph.endIndex, paragraph); | |||
| } | |||
| return document; | |||
| } | |||
| @@ -2992,7 +2992,7 @@ namespace Novacode | |||
| { | |||
| string header_uri = string.Format("/word/{0}{1}.xml", reference, i); | |||
| PackagePart headerPart = package.CreatePart(new Uri(header_uri, UriKind.Relative), string.Format("application/vnd.openxmlformats-officedocument.wordprocessingml.{0}+xml", reference)); | |||
| PackagePart headerPart = package.CreatePart(new Uri(header_uri, UriKind.Relative), string.Format("application/vnd.openxmlformats-officedocument.wordprocessingml.{0}+xml", reference), CompressionOption.Normal); | |||
| PackageRelationship headerRelationship = mainPart.CreateRelationship(headerPart.Uri, TargetMode.Internal, string.Format("http://schemas.openxmlformats.org/officeDocument/2006/relationships/{0}", reference)); | |||
| XDocument header; | |||
| @@ -3168,7 +3168,7 @@ namespace Novacode | |||
| } while (package.PartExists(new Uri(imgPartUriPath, UriKind.Relative))); | |||
| // We are now guareenteed that imgPartUriPath is unique. | |||
| PackagePart img = package.CreatePart(new Uri(imgPartUriPath, UriKind.Relative), contentType); | |||
| PackagePart img = package.CreatePart(new Uri(imgPartUriPath, UriKind.Relative), contentType, CompressionOption.Normal); | |||
| // Create a new image relationship | |||
| PackageRelationship rel = mainPart.CreateRelationship(img.Uri, TargetMode.Internal, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"); | |||
| @@ -3819,7 +3819,7 @@ namespace Novacode | |||
| customPropDoc.Save(tw, SaveOptions.None); | |||
| // Refresh all fields in this document which display this custom property. | |||
| UpdateCustomPropertyValue(this, cp.Name, (cp.Value ?? "").ToString()); | |||
| UpdateCustomPropertyValue(this, cp.Name, (cp.Value ?? "").ToString()); | |||
| } | |||
| /// <summary> | |||
| @@ -4061,7 +4061,7 @@ namespace Novacode | |||
| } while (package.PartExists(new Uri(chartPartUriPath, UriKind.Relative))); | |||
| // Create chart part. | |||
| PackagePart chartPackagePart = package.CreatePart(new Uri(chartPartUriPath, UriKind.Relative), "application/vnd.openxmlformats-officedocument.drawingml.chart+xml"); | |||
| PackagePart chartPackagePart = package.CreatePart(new Uri(chartPartUriPath, UriKind.Relative), "application/vnd.openxmlformats-officedocument.drawingml.chart+xml", CompressionOption.Normal); | |||
| // Create a new chart relationship | |||
| String relID = GetNextFreeRelationshipID(); | |||
| @@ -4108,7 +4108,7 @@ namespace Novacode | |||
| { | |||
| return InsertTableOfContents("Table of contents", TableOfContentsSwitches.O | TableOfContentsSwitches.H | TableOfContentsSwitches.Z | TableOfContentsSwitches.U); | |||
| } | |||
| /// <summary> | |||
| /// Inserts a TOC into the current document. | |||
| /// </summary> | |||
| @@ -440,11 +440,11 @@ namespace Novacode | |||
| ) | |||
| ); | |||
| XElement tableGrid = new XElement(XName.Get("tblGrid", DocX.w.NamespaceName)); | |||
| /*XElement tableGrid = new XElement(XName.Get("tblGrid", DocX.w.NamespaceName)); | |||
| for (int i = 0; i < columnWidths.Length; i++) | |||
| tableGrid.Add(new XElement(XName.Get("gridCol", DocX.w.NamespaceName), new XAttribute(XName.Get("w", DocX.w.NamespaceName), XmlConvert.ToString(columnWidths[i])))); | |||
| newTable.Add(tableGrid); | |||
| newTable.Add(tableGrid);*/ | |||
| for (int i = 0; i < rowCount; i++) | |||
| { | |||
| @@ -464,14 +464,14 @@ namespace Novacode | |||
| /// <summary> | |||
| /// Create and return a cell of a table | |||
| /// </summary> | |||
| internal static XElement CreateTableCell() | |||
| internal static XElement CreateTableCell(double w = 2310) | |||
| { | |||
| return 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("w", DocX.w.NamespaceName), w), | |||
| 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))) | |||
| @@ -17,7 +17,7 @@ namespace Novacode | |||
| { | |||
| private Alignment alignment; | |||
| private AutoFit autofit; | |||
| private float[] ColumnWidths; | |||
| /// <summary> | |||
| /// Merge cells in given column starting with startRow and ending with endRow. | |||
| /// </summary> | |||
| @@ -189,6 +189,20 @@ namespace Novacode | |||
| } | |||
| } | |||
| public void SetWidths(float[] widths) | |||
| { | |||
| this.ColumnWidths = widths; | |||
| //set widths for existing rows | |||
| foreach (var r in Rows) | |||
| { | |||
| for (var c = 0; c < widths.Length; c++) | |||
| { | |||
| if (r.Cells.Count > c) | |||
| r.Cells[c].Width = widths[c]; | |||
| } | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// If the tblPr element doesent exist it is created, either way it is returned by this function. | |||
| /// </summary> | |||
| @@ -220,6 +234,7 @@ namespace Novacode | |||
| } | |||
| } | |||
| private int _cachedColCount = -1; | |||
| /// <summary> | |||
| /// Returns the number of columns in this table. | |||
| /// </summary> | |||
| @@ -229,7 +244,9 @@ namespace Novacode | |||
| { | |||
| if (RowCount == 0) | |||
| return 0; | |||
| return Rows.First().ColumnCount; | |||
| if (_cachedColCount == -1) | |||
| _cachedColCount = Rows.First().ColumnCount; | |||
| return _cachedColCount; | |||
| } | |||
| } | |||
| @@ -321,14 +338,14 @@ namespace Novacode | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// String containing the Table Caption value (the table's Alternate Text Title) | |||
| /// </summary> | |||
| private string _tableCaption; | |||
| /// <summary> | |||
| /// Gets or Sets the value of the Table Caption (Alternate Text Title) of this table. | |||
| /// </summary> | |||
| public string TableCaption | |||
| /// <summary> | |||
| /// String containing the Table Caption value (the table's Alternate Text Title) | |||
| /// </summary> | |||
| private string _tableCaption; | |||
| /// <summary> | |||
| /// Gets or Sets the value of the Table Caption (Alternate Text Title) of this table. | |||
| /// </summary> | |||
| public string TableCaption | |||
| { | |||
| set | |||
| { | |||
| @@ -343,7 +360,7 @@ namespace Novacode | |||
| tblCaption = new XElement(XName.Get("tblCaption", DocX.w.NamespaceName), | |||
| new XAttribute(XName.Get("val", DocX.w.NamespaceName), value)); | |||
| tblPr.Add(tblCaption); | |||
| tblPr.Add(tblCaption); | |||
| } | |||
| } | |||
| @@ -1194,6 +1211,7 @@ namespace Novacode | |||
| foreach (Row r in Rows) | |||
| r.Cells[index].Xml.Remove(); | |||
| _cachedColCount = -1; | |||
| } | |||
| /// <summary> | |||
| @@ -1232,7 +1250,10 @@ namespace Novacode | |||
| List<XElement> content = new List<XElement>(); | |||
| for (int i = 0; i < ColumnCount; i++) | |||
| { | |||
| XElement cell = HelperFunctions.CreateTableCell(); | |||
| var w = 2310d; | |||
| if (ColumnWidths != null && ColumnWidths.Length > i) | |||
| w = ColumnWidths[i] * 15; | |||
| XElement cell = HelperFunctions.CreateTableCell(w); | |||
| content.Add(cell); | |||
| } | |||
| @@ -1320,6 +1341,7 @@ namespace Novacode | |||
| { | |||
| if (RowCount > 0) | |||
| { | |||
| _cachedColCount = -1; | |||
| foreach (Row r in Rows) | |||
| { | |||
| // create cell | |||
| @@ -1799,80 +1821,80 @@ namespace Novacode | |||
| /// </example> | |||
| /// <param name="borderType">The table border to set</param> | |||
| /// <param name="border">Border object to set the table border</param> | |||
| public void SetBorder(TableBorderType borderType, Border border) | |||
| { | |||
| /* | |||
| * Get the tblPr (table properties) element for this Table, | |||
| * null will be return if no such element exists. | |||
| */ | |||
| XElement tblPr = Xml.Element(XName.Get("tblPr", DocX.w.NamespaceName)); | |||
| if (tblPr == null) | |||
| { | |||
| Xml.SetElementValue(XName.Get("tblPr", DocX.w.NamespaceName), string.Empty); | |||
| tblPr = Xml.Element(XName.Get("tblPr", DocX.w.NamespaceName)); | |||
| } | |||
| /* | |||
| * Get the tblBorders (table borders) element for this Table, | |||
| * null will be return if no such element exists. | |||
| */ | |||
| XElement tblBorders = tblPr.Element(XName.Get("tblBorders", DocX.w.NamespaceName)); | |||
| if (tblBorders == null) | |||
| { | |||
| tblPr.SetElementValue(XName.Get("tblBorders", DocX.w.NamespaceName), string.Empty); | |||
| tblBorders = tblPr.Element(XName.Get("tblBorders", DocX.w.NamespaceName)); | |||
| } | |||
| /* | |||
| * Get the 'borderType' (table border) element for this Table, | |||
| * null will be return if no such element exists. | |||
| */ | |||
| string tbordertype; | |||
| tbordertype = borderType.ToString(); | |||
| // only lower the first char of string (because of insideH and insideV) | |||
| tbordertype = tbordertype.Substring(0, 1).ToLower() + tbordertype.Substring(1); | |||
| XElement tblBorderType = tblBorders.Element(XName.Get(borderType.ToString(), DocX.w.NamespaceName)); | |||
| if (tblBorderType == null) | |||
| { | |||
| tblBorders.SetElementValue(XName.Get(tbordertype, DocX.w.NamespaceName), string.Empty); | |||
| tblBorderType = tblBorders.Element(XName.Get(tbordertype, DocX.w.NamespaceName)); | |||
| } | |||
| // get string value of border style | |||
| string borderstyle = border.Tcbs.ToString().Substring(5); | |||
| borderstyle = borderstyle.Substring(0, 1).ToLower() + borderstyle.Substring(1); | |||
| // The val attribute is used for the border style | |||
| tblBorderType.SetAttributeValue(XName.Get("val", DocX.w.NamespaceName), borderstyle); | |||
| if (border.Tcbs != BorderStyle.Tcbs_nil) | |||
| { | |||
| int size; | |||
| switch (border.Size) | |||
| { | |||
| case BorderSize.one: size = 2; break; | |||
| case BorderSize.two: size = 4; break; | |||
| case BorderSize.three: size = 6; break; | |||
| case BorderSize.four: size = 8; break; | |||
| case BorderSize.five: size = 12; break; | |||
| case BorderSize.six: size = 18; break; | |||
| case BorderSize.seven: size = 24; break; | |||
| case BorderSize.eight: size = 36; break; | |||
| case BorderSize.nine: size = 48; break; | |||
| default: size = 2; break; | |||
| } | |||
| // The sz attribute is used for the border size | |||
| tblBorderType.SetAttributeValue(XName.Get("sz", DocX.w.NamespaceName), (size).ToString()); | |||
| // The space attribute is used for the cell spacing (probably '0') | |||
| tblBorderType.SetAttributeValue(XName.Get("space", DocX.w.NamespaceName), (border.Space).ToString()); | |||
| // The color attribute is used for the border color | |||
| public void SetBorder(TableBorderType borderType, Border border) | |||
| { | |||
| /* | |||
| * Get the tblPr (table properties) element for this Table, | |||
| * null will be return if no such element exists. | |||
| */ | |||
| XElement tblPr = Xml.Element(XName.Get("tblPr", DocX.w.NamespaceName)); | |||
| if (tblPr == null) | |||
| { | |||
| Xml.SetElementValue(XName.Get("tblPr", DocX.w.NamespaceName), string.Empty); | |||
| tblPr = Xml.Element(XName.Get("tblPr", DocX.w.NamespaceName)); | |||
| } | |||
| /* | |||
| * Get the tblBorders (table borders) element for this Table, | |||
| * null will be return if no such element exists. | |||
| */ | |||
| XElement tblBorders = tblPr.Element(XName.Get("tblBorders", DocX.w.NamespaceName)); | |||
| if (tblBorders == null) | |||
| { | |||
| tblPr.SetElementValue(XName.Get("tblBorders", DocX.w.NamespaceName), string.Empty); | |||
| tblBorders = tblPr.Element(XName.Get("tblBorders", DocX.w.NamespaceName)); | |||
| } | |||
| /* | |||
| * Get the 'borderType' (table border) element for this Table, | |||
| * null will be return if no such element exists. | |||
| */ | |||
| string tbordertype; | |||
| tbordertype = borderType.ToString(); | |||
| // only lower the first char of string (because of insideH and insideV) | |||
| tbordertype = tbordertype.Substring(0, 1).ToLower() + tbordertype.Substring(1); | |||
| XElement tblBorderType = tblBorders.Element(XName.Get(borderType.ToString(), DocX.w.NamespaceName)); | |||
| if (tblBorderType == null) | |||
| { | |||
| tblBorders.SetElementValue(XName.Get(tbordertype, DocX.w.NamespaceName), string.Empty); | |||
| tblBorderType = tblBorders.Element(XName.Get(tbordertype, DocX.w.NamespaceName)); | |||
| } | |||
| // get string value of border style | |||
| string borderstyle = border.Tcbs.ToString().Substring(5); | |||
| borderstyle = borderstyle.Substring(0, 1).ToLower() + borderstyle.Substring(1); | |||
| // The val attribute is used for the border style | |||
| tblBorderType.SetAttributeValue(XName.Get("val", DocX.w.NamespaceName), borderstyle); | |||
| if (border.Tcbs != BorderStyle.Tcbs_nil) | |||
| { | |||
| int size; | |||
| switch (border.Size) | |||
| { | |||
| case BorderSize.one: size = 2; break; | |||
| case BorderSize.two: size = 4; break; | |||
| case BorderSize.three: size = 6; break; | |||
| case BorderSize.four: size = 8; break; | |||
| case BorderSize.five: size = 12; break; | |||
| case BorderSize.six: size = 18; break; | |||
| case BorderSize.seven: size = 24; break; | |||
| case BorderSize.eight: size = 36; break; | |||
| case BorderSize.nine: size = 48; break; | |||
| default: size = 2; break; | |||
| } | |||
| // The sz attribute is used for the border size | |||
| tblBorderType.SetAttributeValue(XName.Get("sz", DocX.w.NamespaceName), (size).ToString()); | |||
| // The space attribute is used for the cell spacing (probably '0') | |||
| tblBorderType.SetAttributeValue(XName.Get("space", DocX.w.NamespaceName), (border.Space).ToString()); | |||
| // The color attribute is used for the border color | |||
| tblBorderType.SetAttributeValue(XName.Get("color", DocX.w.NamespaceName), border.Color.ToHex()); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Get a table border | |||
| @@ -2014,7 +2036,7 @@ namespace Novacode | |||
| } | |||
| return b; | |||
| } | |||
| } | |||
| /// <summary> | |||
| @@ -2228,44 +2250,44 @@ namespace Novacode | |||
| /// <summary> | |||
| /// Set to true to make this row the table header row that will be repeated on each page | |||
| /// </summary> | |||
| public bool TableHeader | |||
| { | |||
| get | |||
| { | |||
| XElement trPr = Xml.Element(XName.Get("trPr", DocX.w.NamespaceName)); | |||
| XElement tblHeader = trPr.Element(XName.Get("tblHeader", DocX.w.NamespaceName)); | |||
| if (tblHeader == null) | |||
| { | |||
| return false; | |||
| } | |||
| else | |||
| { | |||
| return true; | |||
| } | |||
| } | |||
| set | |||
| { | |||
| XElement trPr = Xml.Element(XName.Get("trPr", DocX.w.NamespaceName)); | |||
| if (trPr == null) | |||
| { | |||
| Xml.SetElementValue(XName.Get("trPr", DocX.w.NamespaceName), string.Empty); | |||
| trPr = Xml.Element(XName.Get("trPr", DocX.w.NamespaceName)); | |||
| } | |||
| XElement tblHeader = trPr.Element(XName.Get("tblHeader", DocX.w.NamespaceName)); | |||
| if (tblHeader == null && value) | |||
| { | |||
| trPr.SetElementValue(XName.Get("tblHeader", DocX.w.NamespaceName), string.Empty); | |||
| } | |||
| if (tblHeader != null && !value) | |||
| { | |||
| tblHeader.Remove(); | |||
| } | |||
| } | |||
| } | |||
| /// Set to true to make this row the table header row that will be repeated on each page | |||
| /// </summary> | |||
| public bool TableHeader | |||
| { | |||
| get | |||
| { | |||
| XElement trPr = Xml.Element(XName.Get("trPr", DocX.w.NamespaceName)); | |||
| XElement tblHeader = trPr.Element(XName.Get("tblHeader", DocX.w.NamespaceName)); | |||
| if (tblHeader == null) | |||
| { | |||
| return false; | |||
| } | |||
| else | |||
| { | |||
| return true; | |||
| } | |||
| } | |||
| set | |||
| { | |||
| XElement trPr = Xml.Element(XName.Get("trPr", DocX.w.NamespaceName)); | |||
| if (trPr == null) | |||
| { | |||
| Xml.SetElementValue(XName.Get("trPr", DocX.w.NamespaceName), string.Empty); | |||
| trPr = Xml.Element(XName.Get("trPr", DocX.w.NamespaceName)); | |||
| } | |||
| XElement tblHeader = trPr.Element(XName.Get("tblHeader", DocX.w.NamespaceName)); | |||
| if (tblHeader == null && value) | |||
| { | |||
| trPr.SetElementValue(XName.Get("tblHeader", DocX.w.NamespaceName), string.Empty); | |||
| } | |||
| if (tblHeader != null && !value) | |||
| { | |||
| tblHeader.Remove(); | |||
| } | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Allow row to break across pages. | |||
| /// The default value is true: Word will break the contents of the row across pages. | |||
| @@ -2273,48 +2295,48 @@ namespace Novacode | |||
| /// </summary> | |||
| public bool BreakAcrossPages | |||
| { | |||
| get | |||
| { | |||
| XElement trPr = Xml.Element(XName.Get("trPr", DocX.w.NamespaceName)); | |||
| if (trPr == null) | |||
| return true; | |||
| XElement trCantSplit = trPr.Element(XName.Get("cantSplit", DocX.w.NamespaceName)); | |||
| if (trCantSplit == null) | |||
| return true; | |||
| return false; | |||
| } | |||
| set | |||
| { | |||
| if (value == false) | |||
| { | |||
| XElement trPr = Xml.Element(XName.Get("trPr", DocX.w.NamespaceName)); | |||
| if (trPr == null) | |||
| { | |||
| Xml.SetElementValue(XName.Get("trPr", DocX.w.NamespaceName), string.Empty); | |||
| trPr = Xml.Element(XName.Get("trPr", DocX.w.NamespaceName)); | |||
| } | |||
| XElement trCantSplit = trPr.Element(XName.Get("cantSplit", DocX.w.NamespaceName)); | |||
| if (trCantSplit == null) | |||
| trPr.SetElementValue(XName.Get("cantSplit", DocX.w.NamespaceName), string.Empty); | |||
| } | |||
| if (value == true) | |||
| { | |||
| XElement trPr = Xml.Element(XName.Get("trPr", DocX.w.NamespaceName)); | |||
| if (trPr != null) | |||
| { | |||
| XElement trCantSplit = trPr.Element(XName.Get("cantSplit", DocX.w.NamespaceName)); | |||
| if (trCantSplit != null) | |||
| trCantSplit.Remove(); | |||
| } | |||
| } | |||
| } | |||
| get | |||
| { | |||
| XElement trPr = Xml.Element(XName.Get("trPr", DocX.w.NamespaceName)); | |||
| if (trPr == null) | |||
| return true; | |||
| XElement trCantSplit = trPr.Element(XName.Get("cantSplit", DocX.w.NamespaceName)); | |||
| if (trCantSplit == null) | |||
| return true; | |||
| return false; | |||
| } | |||
| set | |||
| { | |||
| if (value == false) | |||
| { | |||
| XElement trPr = Xml.Element(XName.Get("trPr", DocX.w.NamespaceName)); | |||
| if (trPr == null) | |||
| { | |||
| Xml.SetElementValue(XName.Get("trPr", DocX.w.NamespaceName), string.Empty); | |||
| trPr = Xml.Element(XName.Get("trPr", DocX.w.NamespaceName)); | |||
| } | |||
| XElement trCantSplit = trPr.Element(XName.Get("cantSplit", DocX.w.NamespaceName)); | |||
| if (trCantSplit == null) | |||
| trPr.SetElementValue(XName.Get("cantSplit", DocX.w.NamespaceName), string.Empty); | |||
| } | |||
| if (value == true) | |||
| { | |||
| XElement trPr = Xml.Element(XName.Get("trPr", DocX.w.NamespaceName)); | |||
| if (trPr != null) | |||
| { | |||
| XElement trCantSplit = trPr.Element(XName.Get("cantSplit", DocX.w.NamespaceName)); | |||
| if (trCantSplit != null) | |||
| trCantSplit.Remove(); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| /// <summary> | |||
| @@ -3582,5 +3604,5 @@ namespace Novacode | |||
| public bool NoHorizontalBanding { get; set; } | |||
| public bool NoVerticalBanding { get; set; } | |||
| } | |||
| } | |||