Ver código fonte

Merge pull request #28 from cradaydg/Docx-Content=branch

Content and Replacement
master
PrzemyslawKlys 9 anos atrás
pai
commit
36730a6128

+ 52
- 2
DocX/Container.cs Ver arquivo

@@ -11,6 +11,18 @@ namespace Novacode
{
public abstract class Container : DocXElement
{
public virtual ReadOnlyCollection<Content> Contents
{
get
{
List<Content> contents = GetContents();
return contents.AsReadOnly();
}
}
/// <summary>
/// Returns a list of all Paragraphs inside this container.
/// </summary>
@@ -224,14 +236,51 @@ namespace Novacode
public ContainerType ParentContainer;
internal List<Content> GetContents(bool deepSearch = false)
{
// Need some memory that can be updated by the recursive search.
//int index = 0;
List<Content> contents = new List<Content>();
foreach (XElement e in Xml.Descendants(XName.Get("sdt", DocX.w.NamespaceName)))
{
Content content = new Content(Document, e, 0);
XElement el = e.Elements(XName.Get("sdtPr", DocX.w.NamespaceName)).First();
content.Name = GetAttribute(el, "alias", "val");
content.Tag = GetAttribute(el, "tag", "val");
contents.Add(content);
}
return contents;
}
private string GetAttribute(XElement e, string localName, string attributeName)
{
string val = string.Empty;
try
{
val = e.Elements(XName.Get(localName, DocX.w.NamespaceName)).Attributes(XName.Get(attributeName, DocX.w.NamespaceName)).FirstOrDefault().Value;
}
catch (Exception)
{
val = "Missing";
}
return val;
}
internal List<Paragraph> GetParagraphs(bool deepSearch=false)
{
// Need some memory that can be updated by the recursive search.
int index = 0;
List<Paragraph> paragraphs = new List<Paragraph>();
GetParagraphsRecursive(Xml, ref index, ref paragraphs, deepSearch);
foreach (XElement e in Xml.Descendants(XName.Get("p", DocX.w.NamespaceName)))
{
index += HelperFunctions.GetText(e).Length;
Paragraph paragraph = new Paragraph(Document, e, index);
paragraphs.Add(paragraph);
}
// GetParagraphsRecursive(Xml, ref index, ref paragraphs, deepSearch);
return paragraphs;
}
@@ -241,6 +290,7 @@ namespace Novacode
// sdtContent are for PageNumbers inside Headers or Footers, don't go any deeper.
//if (Xml.Name.LocalName == "sdtContent")
// return;
var keepSearching = true;
if (Xml.Name.LocalName == "p")
{

+ 34
- 0
DocX/Content.cs Ver arquivo

@@ -0,0 +1,34 @@
using System;
using System.Linq;
using System.Collections.Generic;
using System.Xml.Linq;

namespace Novacode
{
public class Content : InsertBeforeOrAfter
{

public string Name { get; set; }
public string Tag { get; set; }
public string Text { get; set; }
public List<Content> Sections { get; set; }
public ContainerType ParentContainer;


internal Content(DocX document, XElement xml, int startIndex)
: base(document, xml)
{
}

public void SetText(string newText)
{
string x = this.Tag;
XElement el = Xml;
Xml.Descendants(XName.Get("t", DocX.w.NamespaceName)).First().Value = newText;

}

}
}

+ 18
- 0
DocX/ContentCollection.cs Ver arquivo

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Novacode
{
public class ContentCollection : List<Content>
{
public Content this[string name]
{
get
{
return this.FirstOrDefault(content => string.Equals(content.Name, name, StringComparison.CurrentCultureIgnoreCase));
}
}
}
}

+ 124
- 74
DocX/DocX.cs Ver arquivo

@@ -102,10 +102,10 @@ namespace Novacode
}
}
/// <summary>
/// Bottom margin value in points. 1pt = 1/72 of an inch. Word internally writes docx using units = 1/20th of a point.
/// </summary>
public float MarginBottom
/// <summary>
/// Bottom margin value in points. 1pt = 1/72 of an inch. Word internally writes docx using units = 1/20th of a point.
/// </summary>
public float MarginBottom
{
get
{
@@ -118,10 +118,10 @@ namespace Novacode
}
}
/// <summary>
/// Left margin value in points. 1pt = 1/72 of an inch. Word internally writes docx using units = 1/20th of a point.
/// </summary>
public float MarginLeft
/// <summary>
/// Left margin value in points. 1pt = 1/72 of an inch. Word internally writes docx using units = 1/20th of a point.
/// </summary>
public float MarginLeft
{
get
{
@@ -134,10 +134,10 @@ namespace Novacode
}
}
/// <summary>
/// Right margin value in points. 1pt = 1/72 of an inch. Word internally writes docx using units = 1/20th of a point.
/// </summary>
public float MarginRight
/// <summary>
/// Right margin value in points. 1pt = 1/72 of an inch. Word internally writes docx using units = 1/20th of a point.
/// </summary>
public float MarginRight
{
get
{
@@ -150,10 +150,10 @@ namespace Novacode
}
}
/// <summary>
/// Page width value in points. 1pt = 1/72 of an inch. Word internally writes docx using units = 1/20th of a point.
/// </summary>
public float PageWidth
/// <summary>
/// Page width value in points. 1pt = 1/72 of an inch. Word internally writes docx using units = 1/20th of a point.
/// </summary>
public float PageWidth
{
get
{
@@ -199,10 +199,10 @@ namespace Novacode
}
}
/// <summary>
/// Page height value in points. 1pt = 1/72 of an inch. Word internally writes docx using units = 1/20th of a point.
/// </summary>
public float PageHeight
/// <summary>
/// Page height value in points. 1pt = 1/72 of an inch. Word internally writes docx using units = 1/20th of a point.
/// </summary>
public float PageHeight
{
get
{
@@ -224,7 +224,7 @@ namespace Novacode
}
}
return (15840.0f / 20.0f);
return (15840.0f / 20.0f);
}
set
@@ -1058,13 +1058,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);
@@ -1220,7 +1220,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;
@@ -1359,13 +1359,13 @@ namespace Novacode
// Add the remote documents contents to this document.
XElement local_body = mainDoc.Root.Element(XName.Get("body", DocX.w.NamespaceName));
if (append)
local_body.Add(remote_body.Elements());
else
local_body.AddFirst(remote_body.Elements());
if (append)
local_body.Add(remote_body.Elements());
else
local_body.AddFirst(remote_body.Elements());
// Copy any missing root attributes to the local document.
foreach (XAttribute a in remote_mainDoc.Root.Attributes())
// Copy any missing root attributes to the local document.
foreach (XAttribute a in remote_mainDoc.Root.Attributes())
{
if (mainDoc.Root.Attribute(a.Name) == null)
{
@@ -1381,9 +1381,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;
@@ -1479,30 +1479,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)
@@ -1727,10 +1727,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)
@@ -1903,7 +1903,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)
{
@@ -2456,7 +2456,7 @@ namespace Novacode
if (!document.paragraphLookup.ContainsKey(paragraph.endIndex))
document.paragraphLookup.Add(paragraph.endIndex, paragraph);
}
return document;
}
@@ -3409,7 +3409,7 @@ namespace Novacode
public void Save()
{
Headers headers = Headers;
// Save the main document
using (TextWriter tw = new StreamWriter(mainPart.GetStream(FileMode.Create, FileAccess.Write)))
mainDoc.Save(tw, SaveOptions.None);
@@ -4011,7 +4011,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>
@@ -4048,10 +4048,10 @@ namespace Novacode
documents.Add(footers.even.Xml);
#endregion
var matchCustomPropertyName = customPropertyName;
if (customPropertyName.Contains(" ")) matchCustomPropertyName = "\"" + customPropertyName + "\"";
string match_value = string.Format(@"DOCPROPERTY {0} \* MERGEFORMAT", matchCustomPropertyName).Replace(" ", string.Empty);
var matchCustomPropertyName = customPropertyName;
if (customPropertyName.Contains(" ")) matchCustomPropertyName = "\"" + customPropertyName + "\"";
string match_value = string.Format(@"DOCPROPERTY {0} \* MERGEFORMAT", matchCustomPropertyName).Replace(" ", string.Empty);
// Process each document in the list.
foreach (XElement doc in documents)
{
@@ -4106,7 +4106,7 @@ namespace Novacode
foreach (XElement e in doc.Descendants(XName.Get("fldSimple", w.NamespaceName)))
{
string attr_value = e.Attribute(XName.Get("instr", w.NamespaceName)).Value.Replace(" ", string.Empty).Trim();
if (attr_value.Equals(match_value, StringComparison.CurrentCultureIgnoreCase))
{
XElement firstRun = e.Element(w + "r");
@@ -4193,6 +4193,56 @@ namespace Novacode
return paragraphs.ToArray();
}
public override ReadOnlyCollection<Content> Contents
{
get
{
ReadOnlyCollection<Content> l = base.Contents;
foreach (var content in l)
{
content.PackagePart = mainPart;
}
return l;
}
}
public void SetContent(XElement el)
{
foreach (XElement e in el.Elements())
{
(from d in Document.Contents
where d.Name == e.Name
select d).First().SetText(e.Value);
}
}
public void SetContent(Dictionary<string, string> dict)
{
foreach (KeyValuePair<string, string> item in dict)
{
(from d in Document.Contents
where d.Name == item.Key
select d).First().SetText(item.Value);
}
}
public void SetContent(string path)
{
XDocument doc = XDocument.Load(path);
SetContent(doc);
}
public void SetContent(XDocument xmlDoc)
{
foreach (XElement e in xmlDoc.ElementsAfterSelf())
{
(from d in Document.Contents
where d.Name == e.Name
select d).First().SetText(e.Value);
}
}
public override ReadOnlyCollection<Paragraph> Paragraphs
{
get

+ 3
- 0
DocX/DocX.csproj Ver arquivo

@@ -101,6 +101,8 @@
<Compile Include="Charts\PieChart.cs" />
<Compile Include="Charts\XElementHelpers.cs" />
<Compile Include="Container.cs" />
<Compile Include="Content.cs" />
<Compile Include="ContentCollection.cs" />
<Compile Include="DocumentTypes.cs" />
<Compile Include="ExtensionsHeadings.cs" />
<Compile Include="Footers.cs" />
@@ -112,6 +114,7 @@
<Compile Include="Headers.cs" />
<Compile Include="HelperFunctions.cs" />
<Compile Include="Hyperlink.cs" />
<Compile Include="IContentContainer.cs" />
<Compile Include="IParagraphContainer.cs" />
<Compile Include="List.cs" />
<Compile Include="PageLayout.cs" />

+ 9
- 0
DocX/IContentContainer.cs Ver arquivo

@@ -0,0 +1,9 @@
using System.Collections.ObjectModel;

namespace Novacode
{
interface IContentContainer
{
ReadOnlyCollection<Content> Paragraphs { get; }
}
}

BIN
DocX/bin/Debug/DocX.dll Ver arquivo


+ 59
- 6
Examples/Program.cs Ver arquivo

@@ -6,6 +6,7 @@ using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using System.Threading.Tasks;
using Image = Novacode.Image;
@@ -17,6 +18,16 @@ namespace Examples
static void Main(string[] args)
{
Setup();
HelloWorld();
//Contents();
AddList();
Console.ReadLine();
// Examples();
}
static void Examples()
{
// Setup();
// Easy
Console.WriteLine("\nRunning Easy Examples");
HelloWorld();
@@ -216,9 +227,49 @@ namespace Examples
}
#endregion
/// <summary>
/// Load a document and set content controls.
/// </summary>
private static void Contents()
{
Console.WriteLine("\tContent()");
// Load a document.
using (DocX document = DocX.Load(@"docs\Content.docx"))
{
foreach (var c in document.Contents)
{
Console.WriteLine(String.Format("Name : {0}, Tag : {1}", c.Name, c.Tag));
}
(from d in document.Contents
where d.Name == "Name"
select d).First().SetText("NewerText");
document.SaveAs(@"docs\ContentSetSingle.docx");
XElement el = new XElement("Root",
new XElement("Name", "Claudia"),
new XElement("Address", "17 Liberty St"),
new XElement("Total", "123.45")
);
XDocument doc = new XDocument(el);
document.SetContent(el);
document.SaveAs(@"docs\ContentSetWithElement.docx");
doc.Save(@"docs\elements.xml");
document.SetContent(@"docs\elements.xml");
document.SaveAs(@"docs\ContentSetWithPath.docx");
}
}
/// <summary>
/// Create a document with two equations.
/// Create a document wit(h two equations.
/// </summary>
private static void Equations()
{
@@ -667,17 +718,19 @@ namespace Examples
using (var document = DocX.Create(@"docs\Lists.docx"))
{
var numberedList = document.AddList("First List Item.", 0, ListItemType.Numbered, 2);
document.AddListItem(numberedList, "First sub list item", 1);
var numberedList = document.AddList("First List Item.", 0, ListItemType.Numbered);
//Add a numbered list starting at 2
document.AddListItem(numberedList, "Second List Item.");
document.AddListItem(numberedList, "Third list item.");
document.AddListItem(numberedList, "Nested item.", 1);
document.AddListItem(numberedList, "Second nested item.", 1);
document.AddListItem(numberedList, "First sub list item", 1);
document.AddListItem(numberedList, "Nested item.", 2);
document.AddListItem(numberedList, "Fourth nested item.");
var bulletedList = document.AddList("First Bulleted Item.", 0, ListItemType.Bulleted);
document.AddListItem(bulletedList, "Second bullet item");
document.AddListItem(bulletedList, "Sub bullet item", 1);
document.AddListItem(bulletedList, "Second sub bullet item", 1);
document.AddListItem(bulletedList, "Second sub bullet item", 2);
document.AddListItem(bulletedList, "Third bullet item");
document.InsertList(numberedList);

Carregando…
Cancelar
Salvar