coffeycathal_cp 16 년 전
부모
커밋
c1a32b343f
18개의 변경된 파일0개의 추가작업 그리고 3553개의 파일을 삭제
  1. 0
    77
      DocX/CustomProperty.cs
  2. 0
    993
      DocX/DocX.cs
  3. 0
    89
      DocX/DocX.csproj
  4. 0
    10
      DocX/DocX.csproj.vspscc
  5. 0
    31
      DocX/DocX.sln
  6. 0
    10
      DocX/DocX.vssscc
  7. 0
    272
      DocX/Enumerations.cs
  8. 0
    32
      DocX/Extensions.cs
  9. 0
    331
      DocX/Formatting.cs
  10. BIN
      DocX/Help/Documentation.chm
  11. 0
    32
      DocX/Image.cs
  12. 0
    7
      DocX/License/License.html
  13. 0
    978
      DocX/Paragraph.cs
  14. 0
    389
      DocX/Picture.cs
  15. 0
    36
      DocX/Properties/AssemblyInfo.cs
  16. 0
    119
      DocX/Run.cs
  17. 0
    143
      DocX/Text.cs
  18. 0
    4
      DocX/app.config

+ 0
- 77
DocX/CustomProperty.cs 파일 보기

@@ -1,77 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace Novacode
{
/// <summary>
/// Represents a document custom property.
/// </summary>
public class CustomProperty
{
// The underlying XElement which this CustomProperty wraps
private XElement xml;
// This customPropertys name
private string name;
// This customPropertys type
private CustomPropertyType type;
// This customPropertys value
private object value;
/// <summary>
/// Custom Propertys name.
/// </summary>
public string Name { get { return name; } }
/// <summary>
/// Custom Propertys type.
/// </summary>
public CustomPropertyType Type { get { return type; } }
/// <summary>
/// Custom Propertys value.
/// </summary>
public object Value { get { return value; } }
internal CustomProperty(XElement xml)
{
this.xml = xml;
name = xml.Attribute(XName.Get("name")).Value;
XElement p = xml.Elements().SingleOrDefault();
switch (p.Name.LocalName)
{
case "i4":
type = CustomPropertyType.NumberInteger;
value = int.Parse(p.Value);
break;
case "r8":
type = CustomPropertyType.NumberDecimal;
value = double.Parse(p.Value);
break;
case "lpwstr":
type = CustomPropertyType.Text;
value = p.Value;
break;
case "filetime":
type = CustomPropertyType.Date;
value = DateTime.Parse(p.Value);
break;
case "bool":
type = CustomPropertyType.YesOrNo;
value = bool.Parse(p.Value);
break;
default:
throw new Exception(string.Format("The custom property type {0} is not supported", p.Name.LocalName));
}
}
}
}

+ 0
- 993
DocX/DocX.cs 파일 보기

@@ -1,993 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DocumentFormat.OpenXml.Packaging;
using System.Xml.Linq;
using System.Xml;
using System.IO;
using System.Text.RegularExpressions;
namespace Novacode
{
/// <summary>
/// Represents a document.
/// </summary>
public class DocX
{
// A lookup for the runs in this paragraph
internal static Dictionary<int, Paragraph> paragraphLookup = new Dictionary<int, Paragraph>();
static internal string editSessionID;
static internal XNamespace w = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
internal DocX()
{
editSessionID = Guid.NewGuid().ToString().Substring(0, 8);
}
#region Private static variable declarations
// Object representation of the .docx
private static WordprocessingDocument wdDoc;
// Object representation of the \word\document.xml part
internal static MainDocumentPart mainDocumentPart;
// Object representation of the \docProps\custom.xml part
private static CustomFilePropertiesPart customPropertiesPart = null;
// The mainDocument is loaded into a XDocument object for easy querying and editing
private static XDocument mainDoc;
// The customPropertyDocument is loaded into a XDocument object for easy querying and editing
private static XDocument customPropDoc;
// The collection of Paragraphs <w:p></w:p> in this .docx
private static List<Paragraph> paragraphs = new List<Paragraph>();
// The collection of custom properties in this .docx
private static List<CustomProperty> customProperties;
private static List<Image> images;
private static XNamespace customPropertiesSchema = "http://schemas.openxmlformats.org/officeDocument/2006/custom-properties";
private static XNamespace customVTypesSchema = "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes";
private Random random = new Random();
#endregion
/// <summary>
/// Returns a list of Paragraphs in this document.
/// </summary>
/// <example>
/// Write to Console the Text from each Paragraph in this document.
/// <code>
/// // Load a document
/// DocX document = DocX.Load(@"C:\Example\Test.docx");
///
/// // Loop through each Paragraph in this document.
/// foreach (Paragraph p in document.Paragraphs)
/// {
/// // Write this Paragraphs Text to Console.
/// Console.WriteLine(p.Text);
/// }
///
/// // Always close your document when you are finished with it.
/// document.Close(false);
///
/// // Wait for the user to press a key before closing the console window.
/// Console.ReadKey();
/// </code>
/// </example>
/// <seealso cref="Paragraph.InsertText(string, bool)"/>
/// <seealso cref="Paragraph.InsertText(int, string, bool)"/>
/// <seealso cref="Paragraph.InsertText(string, bool, Formatting)"/>
/// <seealso cref="Paragraph.InsertText(int, string, bool, Formatting)"/>
/// <seealso cref="Paragraph.RemoveText(int, bool)"/>
/// <seealso cref="Paragraph.RemoveText(int, int, bool)"/>
/// <seealso cref="Paragraph.ReplaceText(string, string, bool)"/>
/// <seealso cref="Paragraph.ReplaceText(string, string, bool, RegexOptions)"/>
/// <seealso cref="Paragraph.InsertPicture"/>
public List<Paragraph> Paragraphs
{
get { return paragraphs; }
}
/// <summary>
/// Returns a list of Images in this document.
/// </summary>
/// <example>
/// Get the unique Id of every Image in this document.
/// <code>
/// // Load a document.
/// DocX document = DocX.Load(@"C:\Example\Test.docx");
///
/// // Loop through each Image in this document.
/// foreach (Novacode.Image i in document.Images)
/// {
/// // Get the unique Id which identifies this Image.
/// string uniqueId = i.Id;
/// }
///
/// // Always close your document when you are finished with it.
/// document.Close(false);
/// </code>
/// </example>
/// <seealso cref="AddImage(string)"/>
/// <seealso cref="AddImage(Stream)"/>
/// <seealso cref="Paragraph.Pictures"/>
/// <seealso cref="Paragraph.InsertPicture"/>
public List<Image> Images
{
get { return images; }
}
/// <summary>
/// Returns a list of custom properties in this document.
/// </summary>
/// <example>
/// Get the name, type and value of each CustomProperty in this document.
/// <code>
/// // Load Example.docx
/// DocX document = DocX.Load(@"C:\Example\Test.docx");
///
/// // Loop through each CustomProperty in this document
/// foreach (CustomProperty cp in document.CustomProperties)
/// {
/// string name = cp.Name;
/// CustomPropertyType type = cp.Type;
/// object value = cp.Value;
/// }
///
/// // Always close your document when you are finished with it.
/// document.Close(false);
/// </code>
/// </example>
/// <seealso cref="AddCustomProperty"/>
public List<CustomProperty> CustomProperties
{
get { return customProperties; }
}
static internal void RebuildParagraphs()
{
paragraphLookup.Clear();
paragraphs.Clear();
// Get the runs in this paragraph
IEnumerable<XElement> paras = 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(startIndex, par);
// Add to paragraph list
paragraphs.Add(xp);
// Only add runs which contain text
if (Paragraph.GetElementTextLength(par) > 0)
{
paragraphLookup.Add(xp.endIndex, xp);
startIndex = xp.endIndex;
}
}
}
/// <summary>
/// Insert a new Paragraph at the end of this document.
/// </summary>
/// <param name="text">The text of this Paragraph.</param>
/// <param name="trackChanges">Should this insertion be tracked as a change?</param>
/// <returns>A new Paragraph.</returns>
/// <example>
/// Inserting a new Paragraph at the end of a document with text formatting.
/// <code>
/// // Load a document.
/// DocX document = DocX.Load(@"C:\Example\Test.docx");
///
/// // Insert a new Paragraph at the end of this document.
/// document.InsertParagraph("New text", false);
///
/// // Always close your document when you are finished with it.
/// document.Close(true);
/// </code>
/// </example>
public Paragraph InsertParagraph(string text, bool trackChanges)
{
int index = 0;
if (paragraphLookup.Keys.Count() > 0)
index = paragraphLookup.Last().Key;
return InsertParagraph(index, text, trackChanges, null);
}
/// <summary>
/// Insert a new Paragraph at the end of a document with text formatting.
/// </summary>
/// <param name="text">The text of this Paragraph.</param>
/// <param name="trackChanges">Should this insertion be tracked as a change?</param>
/// <param name="formatting">The formatting for the text of this Paragraph.</param>
/// <returns>A new Paragraph.</returns>
/// <example>
/// Inserting a new Paragraph at the end of a document with text formatting.
/// <code>
/// // Load a document.
/// DocX document = DocX.Load(@"C:\Example\Test.docx");
///
/// // Create a Formatting object
/// Formatting formatting = new Formatting();
/// formatting.Bold = true;
/// formatting.FontColor = Color.Red;
/// formatting.Size = 30;
///
/// // Insert a new Paragraph at the end of this document with text formatting.
/// document.InsertParagraph("New text", false, formatting);
///
/// // Always close your document when you are finished with it.
/// document.Close(true);
/// </code>
/// </example>
public Paragraph InsertParagraph(string text, bool trackChanges, Formatting formatting)
{
int index = 0;
if (paragraphLookup.Keys.Count() > 0)
index = paragraphLookup.Last().Key;
return InsertParagraph(index, text, trackChanges, formatting);
}
/// <summary>
/// Get the Text of this document.
/// </summary>
/// <example>
/// Write to Console the Text from this document.
/// <code>
/// // Load a document
/// DocX document = DocX.Load(@"C:\Example\Test.docx");
///
/// // Get the text of this document.
/// string text = document.Text;
///
/// // Write the text of this document to Console.
/// Console.Write(text);
///
/// // Wait for the user to press a key before closing the console window.
/// Console.ReadKey();
/// </code>
/// </example>
public string Text
{
get
{
string text = string.Empty;
foreach (Paragraph p in paragraphs)
{
text += p.Text + "\n";
}
return text;
}
}
/// <summary>
/// Insert a new Paragraph into this document at a specified index.
/// </summary>
/// <param name="index">The character index to insert this document at.</param>
/// <param name="text">The text of this Paragraph.</param>
/// <param name="trackChanges">Should this insertion be tracked as a change?</param>
/// <returns>A new Paragraph.</returns>
/// <example>
/// Insert a new Paragraph into the middle of a document.
/// <code>
/// // Load a document.
/// DocX document = DocX.Load(@"C:\Example\Test.docx");
///
/// // Middle character index of this document.
/// int index = document.Text.Length / 2;
///
/// // Insert a new Paragraph at the middle of this document.
/// document.InsertParagraph(index, "New text", false);
///
/// // Always close your document when you are finished with it.
/// document.Close(true);
/// </code>
/// </example>
public Paragraph InsertParagraph(int index, string text, bool trackChanges)
{
return InsertParagraph(index, text, trackChanges, null);
}
/// <summary>
/// Insert a new Paragraph into this document at a specified index with text formatting.
/// </summary>
/// <param name="index">The character index to insert this document at.</param>
/// <param name="text">The text of this Paragraph.</param>
/// <param name="trackChanges">Should this insertion be tracked as a change?</param>
/// <param name="formatting">The formatting for the text of this Paragraph.</param>
/// <returns>A new Paragraph.</returns>
/// /// <example>
/// Insert a new Paragraph into the middle of a document with text formatting.
/// <code>
/// // Load a document.
/// DocX document = DocX.Load(@"C:\Example\Test.docx");
///
/// // Create a Formatting object
/// Formatting formatting = new Formatting();
/// formatting.Bold = true;
/// formatting.FontColor = Color.Red;
/// formatting.Size = 30;
///
/// // Middle character index of this document.
/// int index = document.Text.Length / 2;
///
/// // Insert a new Paragraph in the middle of this document.
/// document.InsertParagraph(index, "New text", false, formatting);
///
/// // Always close your document when you are finished with it.
/// document.Close(true);
/// </code>
/// </example>
public Paragraph InsertParagraph(int index, string text, bool trackChanges, Formatting formatting)
{
Paragraph newParagraph = new Paragraph(index, new XElement(w + "p"));
newParagraph.InsertText(0, text, trackChanges, formatting);
Paragraph firstPar = GetFirstParagraphEffectedByInsert(index);
if (firstPar != null)
{
XElement[] splitParagraph = SplitParagraph(firstPar, index - firstPar.startIndex);
firstPar.xml.ReplaceWith
(
splitParagraph[0],
newParagraph.xml,
splitParagraph[1]
);
}
else
mainDoc.Descendants(XName.Get("body", DocX.w.NamespaceName)).First().Add(newParagraph.xml);
return newParagraph;
}
static internal Paragraph GetFirstParagraphEffectedByInsert(int index)
{
// This document contains no Paragraphs and insertion is at index 0
if (paragraphLookup.Keys.Count() == 0 && index == 0)
return null;
foreach (int paragraphEndIndex in paragraphLookup.Keys)
{
if (paragraphEndIndex >= index)
return paragraphLookup[paragraphEndIndex];
}
throw new ArgumentOutOfRangeException();
}
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(), r.xml.ElementsAfterSelf(), split[1]);
}
if (before.Elements().Count() == 0)
before = null;
if (after.Elements().Count() == 0)
after = null;
return new XElement[] { before, after };
}
/// <summary>
/// Creates a document using a Stream.
/// </summary>
/// <param name="stream">The Stream to create the document from.</param>
/// <returns>Returns a DocX object which represents the document.</returns>
/// <example>
/// Creating a document from a FileStream.
/// <code>
/// // Use a FileStream fs to create a new document.
/// using(FileStream fs = new FileStream(@"C:\Example\Test.docx", FileMode.Create))
/// {
/// // Load the document using fs
/// DocX document = DocX.Load(fs);
///
/// // Do something with the document here.
///
/// // Always close your document when you are finished with it.
/// document.Close(true);
/// }
/// </code>
/// </example>
/// <example>
/// Creating a document in a SharePoint site.
/// <code>
/// // Get the SharePoint site that you want to access.
/// using(SPSite mySite = new SPSite("http://server/sites/site"))
/// {
/// // Open a connection to the SharePoint site
/// using(SPWeb myWeb = mySite.OpenWeb())
/// {
/// // Create a MemoryStream ms.
/// using (MemoryStream ms = new MemoryStream())
/// {
/// // Create a document using ms.
/// DocX document = DocX.Create(ms);
///
/// // Do something with the document here.
///
/// // Always close your document when you are finished with it.
/// document.Close(true);
///
/// // Add the document to the SharePoint site
/// web.Files.Add("filename", ms.ToArray(), true);
/// }
/// }
/// }
/// </code>
/// </example>
/// <seealso cref="DocX.Create(string)"/>
/// <seealso cref="DocX.Load(System.IO.Stream)"/>
/// <seealso cref="DocX.Load(string)"/>
/// <seealso cref="DocX.Close"/>
public static DocX Create(Stream stream)
{
// Create the docx package
wdDoc = WordprocessingDocument.Create(stream, DocumentFormat.OpenXml.WordprocessingDocumentType.Document);
PostCreation();
return DocX.Load(stream);
}
/// <summary>
/// Creates a document using a fully qualified or relative filename.
/// </summary>
/// <param name="filename">The fully qualified or relative filename.</param>
/// <returns>Returns a DocX object which represents the document.</returns>
/// <example>
/// <code>
/// // Create a document using a fully qualified filename
/// DocX document = DocX.Create(@"C:\Example\Test.docx");
///
/// // Do something with the document here.
///
/// // Always close your document when you are finished with it.
/// document.Close(true);
/// </code>
/// <code>
/// // Create a document using a relative filename.
/// DocX document = DocX.Create(@"..\Test.docx");
///
/// // Do something with the document here.
///
/// // Always close your document when you are finished with it.
/// document.Close(true);
/// </code>
/// <seealso cref="DocX.Create(System.IO.Stream)"/>
/// <seealso cref="DocX.Load(System.IO.Stream)"/>
/// <seealso cref="DocX.Load(string)"/>
/// <seealso cref="DocX.Close"/>
/// </example>
public static DocX Create(string filename)
{
// Create the docx package
wdDoc = WordprocessingDocument.Create(filename, DocumentFormat.OpenXml.WordprocessingDocumentType.Document);
PostCreation();
return DocX.Load(filename);
}
private static void PostCreation()
{
#region MainDocumentPart
// Create the main document part for this package
mainDocumentPart = wdDoc.AddMainDocumentPart();
// Load the document part into a XDocument object
using (TextReader tr = new StreamReader(mainDocumentPart.GetStream(FileMode.Create, FileAccess.ReadWrite)))
{
mainDoc = XDocument.Parse
(@"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?>
<w:document xmlns:ve=""http://schemas.openxmlformats.org/markup-compatibility/2006"" 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:wp=""http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"" xmlns:w10=""urn:schemas-microsoft-com:office:word"" xmlns:w=""http://schemas.openxmlformats.org/wordprocessingml/2006/main"" xmlns:wne=""http://schemas.microsoft.com/office/word/2006/wordml"">
<w:body>
<w:sectPr w:rsidR=""003E25F4"" w:rsidSect=""00FC3028"">
<w:pgSz w:w=""11906"" w:h=""16838""/>
<w:pgMar w:top=""1440"" w:right=""1440"" w:bottom=""1440"" w:left=""1440"" w:header=""708"" w:footer=""708"" w:gutter=""0""/>
<w:cols w:space=""708""/>
<w:docGrid w:linePitch=""360""/>
</w:sectPr>
</w:body>
</w:document>"
);
}
RebuildParagraphs();
#endregion
#region CustomFilePropertiesPart
// Get the custom file properties part from the package
customPropertiesPart = wdDoc.CustomFilePropertiesPart;
// This docx contains a customFilePropertyPart
if (customPropertiesPart != null)
{
// Load the customFilePropertyPart
using (TextReader tr = new StreamReader(customPropertiesPart.GetStream(FileMode.Open, FileAccess.Read)))
{
customPropDoc = XDocument.Load(tr, LoadOptions.PreserveWhitespace);
}
// Get all of the custom properties in this document
DocX.customProperties = (from cp in customPropDoc.Descendants(XName.Get("property", customPropertiesSchema.NamespaceName))
select new CustomProperty(cp)).ToList();
}
#endregion
DocX created = new DocX();
created.Close(true);
}
private static DocX PostLoad()
{
#region MainDocumentPart
// Get the main document part from the package
mainDocumentPart = wdDoc.MainDocumentPart;
// Load the document part into a XDocument object
using (TextReader tr = new StreamReader(mainDocumentPart.GetStream(FileMode.Open, FileAccess.Read)))
{
mainDoc = XDocument.Load(tr, LoadOptions.PreserveWhitespace);
}
RebuildParagraphs();
DocX.images = (from i in mainDocumentPart.ImageParts
select new Image(i)).ToList();
#endregion
#region CustomFilePropertiesPart
// Get the custom file properties part from the package
customPropertiesPart = wdDoc.CustomFilePropertiesPart;
// This docx contains a customFilePropertyPart
if (customPropertiesPart != null)
{
// Load the customFilePropertyPart
using (TextReader tr = new StreamReader(customPropertiesPart.GetStream(FileMode.Open, FileAccess.Read)))
{
customPropDoc = XDocument.Load(tr, LoadOptions.PreserveWhitespace);
}
// Get all of the custom properties in this document
DocX.customProperties = (from cp in customPropDoc.Descendants(XName.Get("property", customPropertiesSchema.NamespaceName))
select new CustomProperty(cp)).ToList();
}
#endregion
return new DocX();
}
/// <summary>
/// Loads a document into a DocX object using a Stream.
/// </summary>
/// <param name="stream">The Stream to load the document from.</param>
/// <returns>
/// Returns a DocX object which represents the document.
/// </returns>
/// <example>
/// Loading a document from a FileStream.
/// <code>
/// // Open a FileStream fs to a document.
/// using(FileStream fs = new FileStream(@"C:\Example\Test.docx", FileMode.Open))
/// {
/// // Load the document using fs
/// DocX document = DocX.Load(fs);
///
/// // Do something with the document here.
///
/// // Always close your document when you are finished with it.
/// document.Close(true);
/// }
/// </code>
/// </example>
/// <example>
/// Loading a document from a SharePoint site.
/// <code>
/// // Get the SharePoint site that you want to access.
/// using(SPSite mySite = new SPSite("http://server/sites/site"))
/// {
/// // Open a connection to the SharePoint site
/// using(SPWeb myWeb = mySite.OpenWeb())
/// {
/// // Grab a document stored on this site.
/// SPFile file = web.GetFile("Source_Folder_Name/Source_File");
///
/// // DocX.Load requires a Stream, so open a Stream to this document.
/// Stream str = new MemoryStream(file.OpenBinary());
///
/// // Load the file using the Stream str.
/// DocX document = DocX.Load(str);
///
/// // Do something with the document here.
///
/// // Always close your document when you are finished with it.
/// document.Close(true);
/// }
/// }
/// </code>
/// </example>
/// <seealso cref="DocX.Load(string)"/>
/// <seealso cref="DocX.Create(System.IO.Stream)"/>
/// <seealso cref="DocX.Create(string)"/>
/// <seealso cref="DocX.Close"/>
public static DocX Load(Stream stream)
{
// Open the docx package
wdDoc = WordprocessingDocument.Open(stream, true);
return PostLoad();
}
/// <summary>
/// Loads a document into a DocX object using a fully qualified or relative filename.
/// </summary>
/// <param name="filename">The fully qualified or relative filename.</param>
/// <returns>
/// Returns a DocX object which represents the document.
/// </returns>
/// <example>
/// <code>
/// // Load a document using its fully qualified filename
/// DocX document = DocX.Load(@"C:\Example\Test.docx");
///
/// // Do something with the document here
///
/// // Always close your document when you are finished with it.
/// document.Close(true);
/// </code>
/// <code>
/// // Load a document using its relative filename.
/// DocX document = DocX.Load(@"..\..\Test.docx");
///
/// // Do something with the document here.
///
/// // Always close your document when you are finished with it.
/// document.Close(true);
/// </code>
/// <seealso cref="DocX.Load(System.IO.Stream)"/>
/// <seealso cref="DocX.Create(System.IO.Stream)"/>
/// <seealso cref="DocX.Create(string)"/>
/// <seealso cref="DocX.Close"/>
/// </example>
public static DocX Load(string filename)
{
if (!File.Exists(filename))
throw new FileNotFoundException(string.Format("File could not be found {0}", filename));
// Open the docx package
wdDoc = WordprocessingDocument.Open(filename, true);
return PostLoad();
}
/// <summary>
/// Add an Image into this document from a fully qualified or relative filename.
/// </summary>
/// <param name="filename">The fully qualified or relative filename.</param>
/// <returns>An Image file.</returns>
/// <example>
/// Add an Image into this document from a fully qualified filename.
/// <code>
/// // Load a document.
/// DocX document = DocX.Load(@"C:\Example\Test.docx");
///
/// // Add an Image from a file.
/// document.AddImage(@"C:\Example\Image.png");
///
/// // Close the document.
/// document.Close(true);
/// </code>
/// </example>
/// <seealso cref="AddImage(System.IO.Stream)"/>
/// <seealso cref="Paragraph.InsertPicture"/>
public Image AddImage(string filename)
{
ImagePart ip = mainDocumentPart.AddImagePart(ImagePartType.Jpeg);
using (Stream stream = ip.GetStream(FileMode.Create, FileAccess.Write))
{
using (Stream s = new FileStream(filename, FileMode.Open))
{
byte[] bytes = new byte[s.Length];
s.Read(bytes, 0, (int)s.Length);
stream.Write(bytes, 0, (int)s.Length);
}
}
return new Image(ip);
}
/// <summary>
/// Add an Image into this document from a Stream.
/// </summary>
/// <param name="stream">A Stream stream.</param>
/// <returns>An Image file.</returns>
/// <example>
/// Add an Image into a document using a Stream.
/// <code>
/// // Open a FileStream fs to an Image.
/// using (FileStream fs = new FileStream(@"C:\Example\Image.jpg", FileMode.Open))
/// {
/// // Load a document.
/// DocX document = DocX.Load(@"C:\Example\Test.docx");
///
/// // Add an Image from a filestream fs.
/// document.AddImage(fs);
///
/// // Close the document.
/// document.Close(true);
/// }
/// </code>
/// </example>
/// <seealso cref="AddImage(string)"/>
/// <seealso cref="Paragraph.InsertPicture"/>
public Image AddImage(Stream stream)
{
ImagePart ip = mainDocumentPart.AddImagePart(ImagePartType.Jpeg);
using (Stream s = ip.GetStream(FileMode.Create, FileAccess.Write))
{
byte[] bytes = new byte[stream.Length];
stream.Read(bytes, 0, (int)stream.Length);
s.Write(bytes, 0, (int)stream.Length);
}
return new Image(ip);
}
/// <summary>
/// Close the document and optionally save pending changes.
/// </summary>
/// <param name="saveChanges">Should pending changes be saved?</param>
/// <example>
/// <code>
/// // Load a document using its fully qualified filename.
/// DocX document = DocX.Load(@"C:\Example\Test.docx");
///
/// // Insert a new Paragraph
/// document.InsertParagraph("Hello world!", false);
///
/// // Should pending changes be saved?
/// bool saveChanges = true;
///
/// // Close the document.
/// document.Close(saveChanges);
/// </code>
/// </example>
/// <seealso cref="DocX.Create(System.IO.Stream)"/>
/// <seealso cref="DocX.Create(string)"/>
/// <seealso cref="DocX.Load(System.IO.Stream)"/>
/// <seealso cref="DocX.Load(string)"/>
public void Close(bool saveChanges)
{
if (saveChanges)
{
if (mainDocumentPart != null)
{
// Save the main document
using (TextWriter tw = new StreamWriter(mainDocumentPart.GetStream(FileMode.Create, FileAccess.Write)))
mainDoc.Save(tw, SaveOptions.DisableFormatting);
}
if (customPropertiesPart != null)
{
// Save the custom properties
using (TextWriter tw = new StreamWriter(customPropertiesPart.GetStream(FileMode.Create, FileAccess.Write)))
customPropDoc.Save(tw, SaveOptions.DisableFormatting);
}
}
// Close and dispose of the file
wdDoc.Close();
wdDoc.Dispose();
}
/// <summary>
/// Adds a new custom property to this document. If a custom property already exists with this name its value is updated.
/// </summary>
/// <param name="name">The name of the custom property.</param>
/// <param name="type">The type of the custom property.</param>
/// <param name="value">The value of the new custom property.</param>
/// <example>
/// Add one of each custom property type to a document.
/// <code>
/// // Load a document.
/// DocX document = DocX.Load(@"C:\Example\Test.docx");
///
/// // Add a custom property 'Name'.
/// document.AddCustomProperty("Name", CustomPropertyType.Text, "Helium");
///
/// // Add a custom property 'Date discovered'.
/// document.AddCustomProperty("Date discovered", CustomPropertyType.Date, new DateTime(1868, 08, 18));
///
/// // Add a custom property 'Noble gas'.
/// document.AddCustomProperty("Noble gas", CustomPropertyType.YesOrNo, true);
///
/// // Add a custom property 'Atomic number'.
/// document.AddCustomProperty("Atomic number", CustomPropertyType.NumberInteger, 2);
///
/// // Add a custom property 'Boiling point'.
/// document.AddCustomProperty("Boiling point", CustomPropertyType.NumberDecimal, -268.93);
///
/// // Close the document.
/// document.Close(true);
/// </code>
/// </example>
/// <seealso cref="CustomProperties"/>
public void AddCustomProperty(string name, CustomPropertyType type, object value)
{
string typeString = string.Empty;
string valueString = string.Empty;
switch (type)
{
case CustomPropertyType.Text:
{
if (!(value is string))
throw new Exception("Not a string");
typeString = "lpwstr";
valueString = value as string;
break;
}
case CustomPropertyType.Date:
{
if (!(value is DateTime))
throw new Exception("Not a DateTime");
typeString = "filetime";
// Must be UTC time
valueString = (((DateTime)value).ToUniversalTime()).ToString();
break;
}
case CustomPropertyType.YesOrNo:
{
if (!(value is bool))
throw new Exception("Not a Boolean");
typeString = "bool";
// Must be lower case either {true or false}
valueString = (((bool)value)).ToString().ToLower();
break;
}
case CustomPropertyType.NumberInteger:
{
if (!(value is int))
throw new Exception("Not an int");
typeString = "i4";
valueString = value.ToString();
break;
}
case CustomPropertyType.NumberDecimal:
{
if (!(value is double))
throw new Exception("Not a double");
typeString = "r8";
valueString = value.ToString();
break;
}
}
// This docx does not contain a customFilePropertyPart
if (customPropertiesPart == null)
{
customPropertiesPart = wdDoc.AddCustomFilePropertiesPart();
customPropDoc = new XDocument(new XDeclaration("1.0", "UTF-8", "yes"),
new XElement(XName.Get("Properties", customPropertiesSchema.NamespaceName),
new XAttribute(XNamespace.Xmlns + "vt", customVTypesSchema),
new XElement(XName.Get("property", customPropertiesSchema.NamespaceName),
new XAttribute("fmtid", "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}"),
new XAttribute("pid", "2"),
new XAttribute("name", name),
new XElement(customVTypesSchema + typeString, value)
)));
}
// This docx contains a customFilePropertyPart
else
{
// Get the highest PID
int pid = (from d in customPropDoc.Descendants()
where d.Name.LocalName == "property"
select int.Parse(d.Attribute(XName.Get("pid")).Value)).Max<int>();
// Get the custom property or null
var customProperty = (from d in customPropDoc.Descendants()
where (d.Name.LocalName == "property") && (d.Attribute(XName.Get("name")).Value == name)
select d).SingleOrDefault();
if (customProperty != null)
{
customProperty.Descendants(XName.Get(typeString, customVTypesSchema.NamespaceName)).SingleOrDefault().ReplaceWith(
new XElement(customVTypesSchema + typeString, value));
}
else
{
XElement propertiesElement = customPropDoc.Element(XName.Get("Properties", customPropertiesSchema.NamespaceName));
propertiesElement.Add(new XElement(XName.Get("property", customPropertiesSchema.NamespaceName),
new XAttribute("fmtid", "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}"),
new XAttribute("pid", pid + 1),
new XAttribute("name", name),
new XElement(customVTypesSchema + typeString, value)
));
}
}
UpdateCustomPropertyValue(name, value.ToString());
}
internal static void UpdateCustomPropertyValue(string customPropertyName, string customPropertyValue)
{
foreach (XElement e in mainDoc.Descendants(XName.Get("fldSimple", w.NamespaceName)))
{
if (e.Attribute(XName.Get("instr", w.NamespaceName)).Value.Equals(string.Format(@" DOCPROPERTY {0} \* MERGEFORMAT ", customPropertyName), StringComparison.CurrentCultureIgnoreCase))
{
XElement firstRun = e.Element(w + "r");
// Delete everything and insert updated text value
e.RemoveNodes();
XElement t = new XElement(w + "t", customPropertyValue);
Novacode.Text.PreserveSpace(t);
e.Add(new XElement(firstRun.Name, firstRun.Attributes(), firstRun.Element(XName.Get("rPr", w.NamespaceName)), t));
}
}
}
internal static void RenumberIDs()
{
IEnumerable<XAttribute> trackerIDs =
(from d in 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();
}
}
}

+ 0
- 89
DocX/DocX.csproj 파일 보기

@@ -1,89 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{E863D072-AA8B-4108-B5F1-785241B37F67}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Novacode</RootNamespace>
<AssemblyName>DocX</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SccProjectName>SAK</SccProjectName>
<SccLocalPath>SAK</SccLocalPath>
<SccAuxPath>SAK</SccAuxPath>
<SccProvider>SAK</SccProvider>
<StartupObject>
</StartupObject>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Debug\DocX.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="DocumentFormat.OpenXml, Version=2.0.3302.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<Reference Include="Microsoft.VisualStudio.TeamSystem.Data.UnitTesting, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.XML" />
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data.DataSetExtensions">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="WindowsBase">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="CustomProperty.cs" />
<Compile Include="Enumerations.cs" />
<Compile Include="Extensions.cs" />
<Compile Include="Formatting.cs" />
<Compile Include="Image.cs" />
<Compile Include="Picture.cs" />
<Compile Include="Paragraph.cs" />
<Compile Include="DocX.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Run.cs" />
<Compile Include="Text.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Help\Documentation.chm" />
</ItemGroup>
<ItemGroup>
<Content Include="License\License.html" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

+ 0
- 10
DocX/DocX.csproj.vspscc 파일 보기

@@ -1,10 +0,0 @@
""
{
"FILE_VERSION" = "9237"
"ENLISTMENT_CHOICE" = "NEVER"
"PROJECT_FILE_RELATIVE_PATH" = ""
"NUMBER_OF_EXCLUDED_FILES" = "0"
"ORIGINAL_PROJECT_FILE_PATH" = ""
"NUMBER_OF_NESTED_PROJECTS" = "0"
"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
}

+ 0
- 31
DocX/DocX.sln 파일 보기

@@ -1,31 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DocX", "DocX\DocX.csproj", "{E863D072-AA8B-4108-B5F1-785241B37F67}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{DF41F5CE-8BCB-40CC-835F-54A3DB7D802F}"
EndProject
Global
GlobalSection(TeamFoundationVersionControl) = preSolution
SccNumberOfProjects = 2
SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
SccTeamFoundationServer = https://tfs08.codeplex.com/
SccLocalPath0 = .
SccProjectUniqueName1 = DocX\\DocX.csproj
SccProjectName1 = DocX
SccLocalPath1 = DocX
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E863D072-AA8B-4108-B5F1-785241B37F67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E863D072-AA8B-4108-B5F1-785241B37F67}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E863D072-AA8B-4108-B5F1-785241B37F67}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E863D072-AA8B-4108-B5F1-785241B37F67}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

+ 0
- 10
DocX/DocX.vssscc 파일 보기

@@ -1,10 +0,0 @@
""
{
"FILE_VERSION" = "9237"
"ENLISTMENT_CHOICE" = "NEVER"
"PROJECT_FILE_RELATIVE_PATH" = ""
"NUMBER_OF_EXCLUDED_FILES" = "0"
"ORIGINAL_PROJECT_FILE_PATH" = ""
"NUMBER_OF_NESTED_PROJECTS" = "0"
"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROJECT"
}

+ 0
- 272
DocX/Enumerations.cs 파일 보기

@@ -1,272 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Novacode
{
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 UnderlineStyle { none, singleLine, doubleLine, thick, dotted, dottedHeavy, dash, dashedHeavy, dashLong, dashLongHeavy, dotDash, dashDotHeavy, dotDotDash, dashDotDotHeavy, wave, wavyHeavy, wavyDouble, words };
public enum StrickThrough { none, strike, doubleStrike };
public enum Misc { none, shadow, outline, outlineShadow, emboss, engrave };
public enum CapsStyle { none, caps, smallCaps };
public enum RectangleShapes
{
rect,
roundRect,
snip1Rect,
snip2SameRect,
snip2DiagRect,
snipRoundRect,
round1Rect,
round2SameRect,
round2DiagRect
};
public enum BasicShapes
{
ellipse,
triangle,
rtTriangle,
parallelogram,
trapezoid,
diamond,
pentagon,
hexagon,
heptagon,
octagon,
decagon,
dodecagon,
pie,
chord,
teardrop,
frame,
halfFrame,
corner,
diagStripe,
plus,
plaque,
can,
cube,
bevel,
donut,
noSmoking,
blockArc,
foldedCorner,
smileyFace,
heart,
lightningBolt,
sun,
moon,
cloud,
arc,
backetPair,
bracePair,
leftBracket,
rightBracket,
leftBrace,
rightBrace
};
public enum BlockArrowShapes
{
rightArrow,
leftArrow,
upArrow,
downArrow,
leftRightArrow,
upDownArrow,
quadArrow,
leftRightUpArrow,
bentArrow,
uturnArrow,
leftUpArrow,
bentUpArrow,
curvedRightArrow,
curvedLeftArrow,
curvedUpArrow,
curvedDownArrow,
stripedRightArrow,
notchedRightArrow,
homePlate,
chevron,
rightArrowCallout,
downArrowCallout,
leftArrowCallout,
upArrowCallout,
leftRightArrowCallout,
quadArrowCallout,
circularArrow
};
public enum EquationShapes
{
mathPlus,
mathMinus,
mathMultiply,
mathDivide,
mathEqual,
mathNotEqual
};
public enum FlowchartShapes
{
flowChartProcess,
flowChartAlternateProcess,
flowChartDecision,
flowChartInputOutput,
flowChartPredefinedProcess,
flowChartInternalStorage,
flowChartDocument,
flowChartMultidocument,
flowChartTerminator,
flowChartPreparation,
flowChartManualInput,
flowChartManualOperation,
flowChartConnector,
flowChartOffpageConnector,
flowChartPunchedCard,
flowChartPunchedTape,
flowChartSummingJunction,
flowChartOr,
flowChartCollate,
flowChartSort,
flowChartExtract,
flowChartMerge,
flowChartOnlineStorage,
flowChartDelay,
flowChartMagneticTape,
flowChartMagneticDisk,
flowChartMagneticDrum,
flowChartDisplay
};
public enum StarAndBannerShapes
{
irregularSeal1,
irregularSeal2,
star4,
star5,
star6,
star7,
star8,
star10,
star12,
star16,
star24,
star32,
ribbon,
ribbon2,
ellipseRibbon,
ellipseRibbon2,
verticalScroll,
horizontalScroll,
wave,
doubleWave
};
public enum CalloutShapes
{
wedgeRectCallout,
wedgeRoundRectCallout,
wedgeEllipseCallout,
cloudCallout,
borderCallout1,
borderCallout2,
borderCallout3,
accentCallout1,
accentCallout2,
accentCallout3,
callout1,
callout2,
callout3,
accentBorderCallout1,
accentBorderCallout2,
accentBorderCallout3
};
/// <summary>
/// Text alignment of a paragraph
/// </summary>
public enum Alignment
{
/// <summary>
/// Align text to the left.
/// </summary>
left,
/// <summary>
/// Center text.
/// </summary>
center,
/// <summary>
/// Align text to the right.
/// </summary>
right,
/// <summary>
/// Align text to both the left and right margins, adding extra space between words as necessary.
/// </summary>
both
};
/// <summary>
/// Paragraph edit types
/// </summary>
public enum EditType
{
/// <summary>
/// A ins is a tracked insertion
/// </summary>
ins,
/// <summary>
/// A del is tracked deletion
/// </summary>
del
}
/// <summary>
/// Custom property types.
/// </summary>
public enum CustomPropertyType
{
/// <summary>
/// System.String
/// </summary>
Text,
/// <summary>
/// System.DateTime
/// </summary>
Date,
/// <summary>
/// System.Int32
/// </summary>
NumberInteger,
/// <summary>
/// System.Double
/// </summary>
NumberDecimal,
/// <summary>
/// System.Boolean
/// </summary>
YesOrNo
}
/// <summary>
/// Text types in a Run
/// </summary>
public enum RunTextType
{
/// <summary>
/// System.String
/// </summary>
Text,
/// <summary>
/// System.String
/// </summary>
DelText,
}
}

+ 0
- 32
DocX/Extensions.cs 파일 보기

@@ -1,32 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
namespace Novacode
{
internal static class Extensions
{
internal static string ToHex(this Color source)
{
byte red = source.R;
byte green = source.G;
byte blue = source.B;
string redHex = red.ToString("X");
if (redHex.Length < 2)
redHex = "0" + redHex;
string blueHex = blue.ToString("X");
if (blueHex.Length < 2)
blueHex = "0" + blueHex;
string greenHex = green.ToString("X");
if (greenHex.Length < 2)
greenHex = "0" + greenHex;
return string.Format("{0}{1}{2}", redHex, greenHex, blueHex);
}
}
}

+ 0
- 331
DocX/Formatting.cs 파일 보기

@@ -1,331 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Drawing;
namespace Novacode
{
/// <summary>
/// A text formatting.
/// </summary>
public class Formatting
{
private XElement rPr;
private bool hidden;
private bool bold;
private bool italic;
private StrickThrough strikethrough;
private Script script;
private Highlight highlight;
private double? size;
private Color? fontColor;
private Color? underlineColor;
private UnderlineStyle underlineStyle;
private Misc misc;
private CapsStyle capsStyle;
private FontFamily fontFamily;
private int? percentageScale;
private int? kerning;
private int? position;
private double? spacing;
/// <summary>
/// A text formatting.
/// </summary>
public Formatting()
{
capsStyle = CapsStyle.none;
strikethrough = StrickThrough.none;
script = Script.none;
highlight = Highlight.none;
underlineStyle = UnderlineStyle.none;
misc = Misc.none;
rPr = new XElement(XName.Get("rPr", DocX.w.NamespaceName));
}
internal XElement Xml
{
get
{
if(spacing.HasValue)
rPr.Add(new XElement(XName.Get("spacing", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), spacing.Value * 20)));
if(position.HasValue)
rPr.Add(new XElement(XName.Get("position", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), position.Value * 2)));
if (kerning.HasValue)
rPr.Add(new XElement(XName.Get("kern", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), kerning.Value * 2)));
if (percentageScale.HasValue)
rPr.Add(new XElement(XName.Get("w", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), percentageScale)));
if(fontFamily != null)
rPr.Add(new XElement(XName.Get("rFonts", DocX.w.NamespaceName), new XAttribute(XName.Get("ascii", DocX.w.NamespaceName), fontFamily.Name)));
if(hidden)
rPr.Add(new XElement(XName.Get("vanish", DocX.w.NamespaceName)));
if (bold)
rPr.Add(new XElement(XName.Get("b", DocX.w.NamespaceName)));
if (italic)
rPr.Add(new XElement(XName.Get("i", DocX.w.NamespaceName)));
switch (underlineStyle)
{
case UnderlineStyle.none:
break;
case UnderlineStyle.singleLine:
rPr.Add(new XElement(XName.Get("u", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), "single")));
break;
case UnderlineStyle.doubleLine:
rPr.Add(new XElement(XName.Get("u", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), "double")));
break;
default:
rPr.Add(new XElement(XName.Get("u", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), underlineStyle.ToString())));
break;
}
if(underlineColor.HasValue)
{
// If an underlineColor has been set but no underlineStyle has been set
if (underlineStyle == UnderlineStyle.none)
{
// Set the underlineStyle to the default
underlineStyle = UnderlineStyle.singleLine;
rPr.Add(new XElement(XName.Get("u", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), "single")));
}
rPr.Element(XName.Get("u", DocX.w.NamespaceName)).Add(new XAttribute(XName.Get("color", DocX.w.NamespaceName), underlineColor.Value.ToHex()));
}
switch (strikethrough)
{
case StrickThrough.none:
break;
case StrickThrough.strike:
rPr.Add(new XElement(XName.Get("strike", DocX.w.NamespaceName)));
break;
case StrickThrough.doubleStrike:
rPr.Add(new XElement(XName.Get("dstrike", DocX.w.NamespaceName)));
break;
default:
break;
}
switch (script)
{
case Script.none:
break;
default:
rPr.Add(new XElement(XName.Get("vertAlign", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), script.ToString())));
break;
}
if (size.HasValue)
{
rPr.Add(new XElement(XName.Get("sz", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), (size * 2).ToString())));
rPr.Add(new XElement(XName.Get("szCs", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), (size * 2).ToString())));
}
if(fontColor.HasValue)
rPr.Add(new XElement(XName.Get("color", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), fontColor.Value.ToHex())));
switch (highlight)
{
case Highlight.none:
break;
default:
rPr.Add(new XElement(XName.Get("highlight", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), highlight.ToString())));
break;
}
switch (capsStyle)
{
case CapsStyle.none:
break;
default:
rPr.Add(new XElement(XName.Get(capsStyle.ToString(), DocX.w.NamespaceName)));
break;
}
switch (misc)
{
case Misc.none:
break;
case Misc.outlineShadow:
rPr.Add(new XElement(XName.Get("outline", DocX.w.NamespaceName)));
rPr.Add(new XElement(XName.Get("shadow", DocX.w.NamespaceName)));
break;
case Misc.engrave:
rPr.Add(new XElement(XName.Get("imprint", DocX.w.NamespaceName)));
break;
default:
rPr.Add(new XElement(XName.Get(misc.ToString(), DocX.w.NamespaceName)));
break;
}
return rPr;
}
}
/// <summary>
/// This formatting will apply Bold.
/// </summary>
public bool Bold { get { return bold; } set { bold = value;} }
/// <summary>
/// This formatting will apply Italic.
/// </summary>
public bool Italic { get { return Italic; } set { italic = value; } }
/// <summary>
/// This formatting will apply StrickThrough.
/// </summary>
public StrickThrough StrikeThrough { get { return strikethrough; } set { strikethrough = value; } }
/// <summary>
/// The script that this formatting should be, normal, superscript or subscript.
/// </summary>
public Script Script { get { return script; } set { script = value; } }
/// <summary>
/// The Size of this text, must be between 0 and 1638.
/// </summary>
public double? Size
{
get { return size; }
set
{
double? temp = value * 2;
if (temp - (int)temp == 0)
{
if(value > 0 && value < 1639)
size = value;
else
throw new ArgumentException("Size", "Value must be in the range 0 - 1638");
}
else
throw new ArgumentException("Size", "Value must be either a whole or half number, examples: 32, 32.5");
}
}
/// <summary>
/// Percentage scale must be one of the following values 200, 150, 100, 90, 80, 66, 50 or 33.
/// </summary>
public int? PercentageScale
{
get { return percentageScale; }
set
{
if ((new int?[] { 200, 150, 100, 90, 80, 66, 50, 33 }).Contains(value))
percentageScale = value;
else
throw new ArgumentOutOfRangeException("PercentageScale", "Value must be one of the following: 200, 150, 100, 90, 80, 66, 50 or 33");
}
}
/// <summary>
/// The Kerning to apply to this text must be one of the following values 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72.
/// </summary>
public int? Kerning
{
get { return kerning; }
set
{
if(new int?[] {8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72}.Contains(value))
kerning = value;
else
throw new ArgumentOutOfRangeException("Kerning", "Value must be one of the following: 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48 or 72");
}
}
/// <summary>
/// Text position must be in the range (-1585 - 1585).
/// </summary>
public int? Position
{
get { return position; }
set
{
if (value > -1585 && value < 1585)
position = value;
else
throw new ArgumentOutOfRangeException("Position", "Value must be in the range -1585 - 1585");
}
}
/// <summary>
/// Text spacing must be in the range (-1585 - 1585).
/// </summary>
public double? Spacing
{
get { return spacing; }
set
{
double? temp = value * 20;
if (temp - (int)temp == 0)
{
if (value > -1585 && value < 1585)
spacing = value;
else
throw new ArgumentException("Spacing", "Value must be in the range: -1584 - 1584");
}
else
throw new ArgumentException("Spacing", "Value must be either a whole or acurate to one decimal, examples: 32, 32.1, 32.2, 32.9");
}
}
/// <summary>
/// The colour of the text.
/// </summary>
public Color? FontColor { get { return fontColor; } set { fontColor = value; } }
/// <summary>
/// Highlight colour.
/// </summary>
public Highlight Highlight { get { return highlight; } set { highlight = value; } }
/// <summary>
/// The Underline style that this formatting applies.
/// </summary>
public UnderlineStyle UnderlineStyle { get { return underlineStyle; } set { underlineStyle = value; } }
/// <summary>
/// The underline colour.
/// </summary>
public Color? UnderlineColor { get { return underlineColor; } set { underlineColor = value; } }
/// <summary>
/// Misc settings.
/// </summary>
public Misc Misc { get { return misc; } set { misc = value; } }
/// <summary>
/// Is this text hidden or visible.
/// </summary>
public bool Hidden { get { return hidden; } set { hidden = value; } }
/// <summary>
/// Capitalization style.
/// </summary>
public CapsStyle CapsStyle { get { return capsStyle; } set { capsStyle = value; } }
/// <summary>
/// The font familt of this formatting.
/// </summary>
public FontFamily FontFamily { get { return FontFamily; } set { fontFamily = value; } }
}
}

BIN
DocX/Help/Documentation.chm 파일 보기


+ 0
- 32
DocX/Image.cs 파일 보기

@@ -1,32 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DocumentFormat.OpenXml.Packaging;
namespace Novacode
{
/// <summary>
/// Represents an Image embedded in a document.
/// </summary>
public class Image
{
/// <summary>
/// A unique id which identifies this Image.
/// </summary>
private string id;
/// <summary>
/// Returns the id of this Image.
/// </summary>
public string Id
{
get {return id;}
}
internal Image(ImagePart ip)
{
id = DocX.mainDocumentPart.GetIdOfPart(ip);
}
}
}

+ 0
- 7
DocX/License/License.html 파일 보기

@@ -1,7 +0,0 @@
<html>
<body>
<div id="licenseTextHolder" style="margin: 1em">
<span id="ctl00_ctl00_MasterContent_Content_licenseText">Microsoft Public License &#40;Ms-PL&#41;<br /><br />This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software.<br /><br />1. Definitions<br /><br />The terms &#34;reproduce,&#34; &#34;reproduction,&#34; &#34;derivative works,&#34; and &#34;distribution&#34; have the same meaning here as under U.S. copyright law.<br /><br />A &#34;contribution&#34; is the original software, or any additions or changes to the software.<br /><br />A &#34;contributor&#34; is any person that distributes its contribution under this license.<br /><br />&#34;Licensed patents&#34; are a contributor&#39;s patent claims that read directly on its contribution.<br /><br />2. Grant of Rights<br /><br />&#40;A&#41; Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.<br /><br />&#40;B&#41; Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and&#47;or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.<br /><br />3. Conditions and Limitations<br /><br />&#40;A&#41; No Trademark License- This license does not grant you rights to use any contributors&#39; name, logo, or trademarks.<br /><br />&#40;B&#41; If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.<br /><br />&#40;C&#41; If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.<br /><br />&#40;D&#41; If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.<br /><br />&#40;E&#41; The software is licensed &#34;as-is.&#34; You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.</span>
</div>
</body>
</html><!-- @SortOrder 2 -->

+ 0
- 978
DocX/Paragraph.cs 파일 보기

@@ -1,978 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Text.RegularExpressions;
using DocumentFormat.OpenXml.Drawing;
using System.Security.Principal;
using System.Collections;
namespace Novacode
{
/// <summary>
/// Represents a document paragraph.
/// </summary>
public class Paragraph
{
// This paragraphs text alignment
private Alignment alignment;
// A lookup for the runs in this paragraph
Dictionary<int, Run> runLookup = new Dictionary<int, Run>();
// The underlying XElement which this Paragraph wraps
internal XElement xml;
internal int startIndex, endIndex;
// A collection of images in this paragraph
private List<Picture> pictures;
/// <summary>
/// Returns a list of Pictures in this Paragraph.
/// </summary>
public List<Picture> Pictures { get { return pictures; } }
internal Paragraph(int startIndex, XElement p)
{
this.startIndex = startIndex;
this.endIndex = startIndex + GetElementTextLength(p);
this.xml = p;
BuildRunLookup(p);
// Get all of the images in this document
pictures = (from i in p.Descendants(XName.Get("drawing", DocX.w.NamespaceName))
select new Picture(i)).ToList();
}
/// <summary>
/// Gets or set this Paragraphs text alignment.
/// </summary>
public Alignment Alignment
{
get { return alignment; }
set
{
alignment = value;
XElement pPr = xml.Element(XName.Get("pPr", DocX.w.NamespaceName));
if (alignment != Novacode.Alignment.left)
{
if (pPr == null)
xml.Add(new XElement(XName.Get("pPr", DocX.w.NamespaceName)));
pPr = xml.Element(XName.Get("pPr", DocX.w.NamespaceName));
XElement jc = pPr.Element(XName.Get("jc", DocX.w.NamespaceName));
if(jc == null)
pPr.Add(new XElement(XName.Get("jc", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), alignment.ToString())));
else
jc.Attribute(XName.Get("val", DocX.w.NamespaceName)).Value = alignment.ToString();
}
else
{
if (pPr != null)
{
XElement jc = pPr.Element(XName.Get("jc", DocX.w.NamespaceName));
if (jc != null)
jc.Remove();
}
}
}
}
/// <summary>
/// Remove this Paragraph from the document.
/// </summary>
/// <param name="trackChanges">Should this remove be tracked as a change?</param>
/// <example>
/// Remove a Paragraph from a document and track it as a change.
/// <code>
/// // Load a document using its fully qualified filename.
/// DocX document = DocX.Create(@"Test.docx");
///
/// // Create and Insert a new Paragraph into this document.
/// Paragraph p = document.InsertParagraph("Hello", false);
///
/// // Remove the Paragraph and track this as a change.
/// p.Remove(true);
///
/// // Close the document.
/// document.Close(true);
/// </code>
/// </example>
public void Remove(bool trackChanges)
{
if (trackChanges)
{
DateTime now = DateTime.Now.ToUniversalTime();
List<XElement> elements = xml.Elements().ToList();
List<XElement> temp = new List<XElement>();
for (int i = 0; i < elements.Count(); i++ )
{
XElement e = elements[i];
if (e.Name.LocalName != "del")
{
temp.Add(e);
e.Remove();
}
else
{
if (temp.Count() > 0)
{
e.AddBeforeSelf(CreateEdit(EditType.del, now, temp.Elements()));
temp.Clear();
}
}
}
if (temp.Count() > 0)
xml.Add(CreateEdit(EditType.del, now, temp));
}
else
{
// Remove this paragraph from the document
xml.Remove();
xml = null;
runLookup.Clear();
runLookup = null;
}
DocX.RebuildParagraphs();
}
private void BuildRunLookup(XElement p)
{
// Get the runs in this paragraph
IEnumerable<XElement> runs = p.Descendants(XName.Get("r", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"));
int startIndex = 0;
// Loop through each run in this paragraph
foreach (XElement run in runs)
{
// Only add runs which contain text
if (GetElementTextLength(run) > 0)
{
Run r = new Run(startIndex, run);
runLookup.Add(r.EndIndex, r);
startIndex = r.EndIndex;
}
}
}
/// <summary>
/// Gets the text value of this Paragraph.
/// </summary>
public string Text
{
// Returns the underlying XElement's Value property.
get
{
StringBuilder sb = new StringBuilder();
// Loop through each run in this paragraph
foreach (XElement r in xml.Descendants(XName.Get("r", DocX.w.NamespaceName)))
{
// Loop through each text item in this run
foreach (XElement descendant in r.Descendants())
{
switch (descendant.Name.LocalName)
{
case "tab":
sb.Append("\t");
break;
case "br":
sb.Append("\n");
break;
case "t":
goto case "delText";
case "delText":
sb.Append(descendant.Value);
break;
default: break;
}
}
}
return sb.ToString();
}
}
/// <summary>
/// Insert a Picture into this document at a specified index.
/// </summary>
/// <param name="picture">The Picture to insert.</param>
/// <param name="index">The index to insert at.</param>
/// <example>
/// <code>
/// // Create a document using a relative filename.
/// DocX document = DocX.Create(@"Test.docx");
///
/// // Add an Image to this document.
/// Novacode.Image img = document.AddImage("Image.jpg");
///
/// // Create a Picture, a picture is like a custom view of an Image.
/// Picture pic = new Picture(img.Id, "Photo 31415", "A pie I baked.");
///
/// // Rotate the Picture clockwise by 30 degrees.
/// pic.Rotation = 30;
///
/// // Resize the Picture.
/// pic.Width = 400;
/// pic.Height = 300;
///
/// // Set the shape of this Picture to be a cube.
/// pic.SetPictureShape(BasicShapes.cube);
///
/// // Flip the Picture Horizontally.
/// pic.FlipHorizontal = true;
///
/// // Add a new Paragraph to this document.
/// Paragraph p = document.InsertParagraph("Here is Picture 1", false);
///
/// // Insert pic at the end of Paragraph p.
/// p.InsertPicture(pic, p.Text.Length);
///
/// // Close the document.
/// document.Close(true);
/// </code>
/// </example>
public void InsertPicture(Picture picture, int index)
{
Run run = GetFirstRunEffectedByEdit(index);
if (run == null)
xml.Add(picture.i);
else
{
// Split this run at the point you want to insert
XElement[] splitRun = Run.SplitRun(run, index);
// Replace the origional run
run.xml.ReplaceWith
(
splitRun[0],
picture.i,
splitRun[1]
);
}
// Rebuild the run lookup for this paragraph
runLookup.Clear();
BuildRunLookup(xml);
DocX.RenumberIDs();
}
/// <summary>
/// Creates an Edit either a ins or a del with the specified content and date
/// </summary>
/// <param name="t">The type of this edit (ins or del)</param>
/// <param name="edit_time">The time stamp to use for this edit</param>
/// <param name="content">The initial content of this edit</param>
/// <returns></returns>
private 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 Run GetFirstRunEffectedByEdit(int index)
{
foreach (int runEndIndex in runLookup.Keys)
{
if (runEndIndex > index)
return runLookup[runEndIndex];
}
if (runLookup.Last().Value.EndIndex == index)
return runLookup.Last().Value;
throw new ArgumentOutOfRangeException();
}
internal Run GetFirstRunEffectedByInsert(int index)
{
// This paragraph contains no Runs and insertion is at index 0
if (runLookup.Keys.Count() == 0 && index == 0)
return null;
foreach (int runEndIndex in runLookup.Keys)
{
if (runEndIndex >= index)
return runLookup[runEndIndex];
}
throw new ArgumentOutOfRangeException();
}
private List<XElement> FormatInput(string text, XElement rPr)
{
// Need to support /n as non breaking space
List<XElement> newRuns = new List<XElement>();
XElement tabRun = new XElement(DocX.w + "tab");
string[] runTexts = text.Split('\t');
XElement firstRun;
if (runTexts[0] != String.Empty)
{
XElement firstText = new XElement(DocX.w + "t", runTexts[0]);
Novacode.Text.PreserveSpace(firstText);
firstRun = new XElement(DocX.w + "r", rPr, firstText);
newRuns.Add(firstRun);
}
if (runTexts.Length > 1)
{
for (int k = 1; k < runTexts.Length; k++)
{
XElement newText = new XElement(DocX.w + "t", runTexts[k]);
XElement newRun;
if (runTexts[k] == String.Empty)
newRun = new XElement(DocX.w + "r", tabRun);
else
{
// Value begins or ends with a space
Novacode.Text.PreserveSpace(newText);
newRun = new XElement(DocX.w + "r", rPr, tabRun, newText);
}
newRuns.Add(newRun);
}
}
return newRuns;
}
static internal int GetElementTextLength(XElement run)
{
int count = 0;
if (run == null)
return count;
foreach (var d in run.Descendants())
{
switch (d.Name.LocalName)
{
case "tab": goto case "br";
case "br": count++; break;
case "t": goto case "delText";
case "delText": count += d.Value.Length; break;
default: break;
}
}
return count;
}
internal XElement[] SplitEdit(XElement edit, int index, EditType type)
{
Run run;
if(type == EditType.del)
run = GetFirstRunEffectedByEdit(index);
else
run = GetFirstRunEffectedByInsert(index);
XElement[] splitRun = Run.SplitRun(run, index);
XElement splitLeft = new XElement(edit.Name, edit.Attributes(), run.xml.ElementsBeforeSelf(), splitRun[0]);
if (GetElementTextLength(splitLeft) == 0)
splitLeft = null;
XElement splitRight = new XElement(edit.Name, edit.Attributes(), splitRun[1], run.xml.ElementsAfterSelf());
if (GetElementTextLength(splitRight) == 0)
splitRight = null;
return
(
new XElement[]
{
splitLeft,
splitRight
}
);
}
/// <summary>
/// Inserts a specified instance of System.String into a Novacode.DocX.Paragraph at a specified index position.
/// </summary>
/// <example>
/// <code>
/// // Load Test.docx.
/// DocX document = DocX.Load(@"C:\Example\Test.docx");
///
/// // Iterate through the Paragraphs in this document.
/// foreach (Paragraph p in document.Paragraphs)
/// {
/// // Insert the string "Start: " at the begining of every Paragraph and flag it as a change.
/// p.InsertText(0, "Start: ", true);
/// }
///
/// // Save changes to this document.
/// document.Close(true);
/// </code>
/// </example>
/// <example>
/// Inserting tabs using the \t switch.
/// <code>
/// // Load Test.docx.
/// DocX document = DocX.Load(@"C:\Example\Test.docx");
///
/// // Iterate through the paragraphs in this document.
/// foreach (Paragraph p in document.Paragraphs)
/// {
/// // Insert the string "\tStart:\t" at the begining of every paragraph and flag it as a change.
/// p.InsertText(0, "\tStart:\t", true);
/// }
///
/// // Save changes to this document.
/// document.Close(true);
/// </code>
/// </example>
/// <seealso cref="Paragraph.RemoveText(int, bool)"/>
/// <seealso cref="Paragraph.RemoveText(int, int, bool)"/>
/// <seealso cref="Paragraph.ReplaceText(string, string, bool)"/>
/// <seealso cref="Paragraph.ReplaceText(string, string, bool, RegexOptions)"/>
/// <param name="index">The index position of the insertion.</param>
/// <param name="value">The System.String to insert.</param>
/// <param name="trackChanges">Flag this insert as a change.</param>
public void InsertText(int index, string value, bool trackChanges)
{
InsertText(index, value, trackChanges, null);
}
/// <summary>
/// Inserts a specified instance of System.String into a Novacode.DocX.Paragraph at a specified index position.
/// </summary>
/// <example>
/// <code>
/// // Load Test.docx.
/// DocX document = DocX.Load(@"C:\Example\Test.docx");
///
/// // Iterate through the Paragraphs in this document.
/// foreach (Paragraph p in document.Paragraphs)
/// {
/// // Insert the string "End: " at the end of every Paragraph and flag it as a change.
/// p.InsertText("End: ", true);
/// }
///
/// // Save changes to this document.
/// document.Close(true);
/// </code>
/// </example>
/// <example>
/// Inserting tabs using the \t switch.
/// <code>
/// // Load Test.docx.
/// DocX document = DocX.Load(@"C:\Example\Test.docx");
///
/// // Iterate through the paragraphs in this document.
/// foreach (Paragraph p in document.Paragraphs)
/// {
/// // Insert the string "\tEnd" at the end of every paragraph and flag it as a change.
/// p.InsertText("\tEnd", true);
/// }
///
/// // Save changes to this document.
/// document.Close(true);
/// </code>
/// </example>
/// <seealso cref="Paragraph.RemoveText(int, bool)"/>
/// <seealso cref="Paragraph.RemoveText(int, int, bool)"/>
/// <seealso cref="Paragraph.ReplaceText(string, string, bool)"/>
/// <seealso cref="Paragraph.ReplaceText(string, string, bool, RegexOptions)"/>
/// <param name="value">The System.String to insert.</param>
/// <param name="trackChanges">Flag this insert as a change.</param>
public void InsertText(string value, bool trackChanges)
{
InsertText(Text.Length, value, trackChanges, null);
}
/// <summary>
/// Inserts a specified instance of System.String into a Novacode.DocX.Paragraph at a specified index position.
/// </summary>
/// <example>
/// <code>
/// // Load Test.docx.
/// DocX document = DocX.Load(@"C:\Example\Test.docx");
///
/// // Create a text formatting.
/// Formatting f = new Formatting();
/// f.FontColor = Color.Red;
/// f.Size = 30;
///
/// // Iterate through the Paragraphs in this document.
/// foreach (Paragraph p in document.Paragraphs)
/// {
/// // Insert the string "Start: " at the begining of every Paragraph and flag it as a change.
/// p.InsertText("Start: ", true, f);
/// }
///
/// // Save changes to this document.
/// document.Close(true);
/// </code>
/// </example>
/// <example>
/// Inserting tabs using the \t switch.
/// <code>
/// // Load Test.docx.
/// DocX document = DocX.Load(@"C:\Example\Test.docx");
///
/// // Create a text formatting.
/// Formatting f = new Formatting();
/// f.FontColor = Color.Red;
/// f.Size = 30;
///
/// // Iterate through the paragraphs in this document.
/// foreach (Paragraph p in document.Paragraphs)
/// {
/// // Insert the string "\tEnd" at the end of every paragraph and flag it as a change.
/// p.InsertText("\tEnd", true, f);
/// }
///
/// // Save changes to this document.
/// document.Close(true);
/// </code>
/// </example>
/// <seealso cref="Paragraph.RemoveText(int, bool)"/>
/// <seealso cref="Paragraph.RemoveText(int, int, bool)"/>
/// <seealso cref="Paragraph.ReplaceText(string, string, bool)"/>
/// <seealso cref="Paragraph.ReplaceText(string, string, bool, RegexOptions)"/>
/// <param name="value">The System.String to insert.</param>
/// <param name="trackChanges">Flag this insert as a change.</param>
/// <param name="formatting">The text formatting.</param>
public void InsertText(string value, bool trackChanges, Formatting formatting)
{
InsertText(Text.Length, value, trackChanges, formatting);
}
/// <summary>
/// Inserts a specified instance of System.String into a Novacode.DocX.Paragraph at a specified index position.
/// </summary>
/// <example>
/// <code>
/// // Load Test.docx.
/// DocX document = DocX.Load(@"C:\Example\Test.docx");
///
/// // Create a text formatting.
/// Formatting f = new Formatting();
/// f.FontColor = Color.Red;
/// f.Size = 30;
///
/// // Iterate through the Paragraphs in this document.
/// foreach (Paragraph p in document.Paragraphs)
/// {
/// // Insert the string "Start: " at the begining of every Paragraph and flag it as a change.
/// p.InsertText(0, "Start: ", true, f);
/// }
///
/// // Save changes to this document.
/// document.Close(true);
/// </code>
/// </example>
/// <example>
/// Inserting tabs using the \t switch.
/// <code>
/// // Load Test.docx.
/// DocX document = DocX.Load(@"C:\Example\Test.docx");
///
/// // Create a text formatting.
/// Formatting f = new Formatting();
/// f.FontColor = Color.Red;
/// f.Size = 30;
///
/// // Iterate through the paragraphs in this document.
/// foreach (Paragraph p in document.Paragraphs)
/// {
/// // Insert the string "\tStart:\t" at the begining of every paragraph and flag it as a change.
/// p.InsertText(0, "\tStart:\t", true, f);
/// }
///
/// // Save changes to this document.
/// document.Close(true);
/// </code>
/// </example>
/// <seealso cref="Paragraph.RemoveText(int, bool)"/>
/// <seealso cref="Paragraph.RemoveText(int, int, bool)"/>
/// <seealso cref="Paragraph.ReplaceText(string, string, bool)"/>
/// <seealso cref="Paragraph.ReplaceText(string, string, bool, RegexOptions)"/>
/// <param name="index">The index position of the insertion.</param>
/// <param name="value">The System.String to insert.</param>
/// <param name="trackChanges">Flag this insert as a change.</param>
/// <param name="formatting">The text formatting.</param>
public void InsertText(int index, string value, bool trackChanges, Formatting formatting)
{
// Timestamp to mark the start of insert
DateTime now = DateTime.Now;
DateTime insert_datetime = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, 0, DateTimeKind.Utc);
// Get the first run effected by this Insert
Run run = GetFirstRunEffectedByInsert(index);
if (run == null)
{
object insert;
if (formatting != null)
insert = FormatInput(value, formatting.Xml);
else
insert = FormatInput(value, null);
if (trackChanges)
insert = CreateEdit(EditType.ins, insert_datetime, insert);
xml.Add(insert);
}
else
{
object newRuns;
if (formatting != null)
newRuns = FormatInput(value, formatting.Xml);
else
newRuns = FormatInput(value, run.xml.Element(XName.Get("rPr", DocX.w.NamespaceName)));
// The parent of this Run
XElement parentElement = run.xml.Parent;
switch (parentElement.Name.LocalName)
{
case "ins":
{
// The datetime that this ins was created
DateTime parent_ins_date = DateTime.Parse(parentElement.Attribute(XName.Get("date", DocX.w.NamespaceName)).Value);
/*
* Special case: You want to track changes,
* and the first Run effected by this insert
* has a datetime stamp equal to now.
*/
if (trackChanges && parent_ins_date.CompareTo(insert_datetime) == 0)
{
/*
* Inserting into a non edit and this special case, is the same procedure.
*/
goto default;
}
/*
* If not the special case above,
* then inserting into an ins or a del, is the same procedure.
*/
goto case "del";
}
case "del":
{
object insert = newRuns;
if (trackChanges)
insert = CreateEdit(EditType.ins, insert_datetime, newRuns);
// Split this Edit at the point you want to insert
XElement[] splitEdit = SplitEdit(parentElement, index, EditType.ins);
// Replace the origional run
parentElement.ReplaceWith
(
splitEdit[0],
insert,
splitEdit[1]
);
break;
}
default:
{
object insert = newRuns;
if (trackChanges && !parentElement.Name.LocalName.Equals("ins"))
insert = CreateEdit(EditType.ins, insert_datetime, newRuns);
// Split this run at the point you want to insert
XElement[] splitRun = Run.SplitRun(run, index);
// Replace the origional run
run.xml.ReplaceWith
(
splitRun[0],
insert,
splitRun[1]
);
break;
}
}
}
// Rebuild the run lookup for this paragraph
runLookup.Clear();
BuildRunLookup(xml);
DocX.RenumberIDs();
}
/// <summary>
/// Removes characters from a Novacode.DocX.Paragraph.
/// </summary>
/// <example>
/// <code>
/// // Load the document Test.docx.
/// DocX document = DocX.Load(@"C:\Example\Test.docx");
///
/// // Iterate through the paragraphs
/// foreach (Paragraph p in document.Paragraphs)
/// {
/// // Remove the first two characters from every paragraph
/// p.RemoveText(0, 2, false);
/// }
///
/// // Save changes to this document.
/// document.Close(true);
/// </code>
/// </example>
/// <seealso cref="Paragraph.ReplaceText(string, string, bool)"/>
/// <seealso cref="Paragraph.ReplaceText(string, string, bool, RegexOptions)"/>
/// <seealso cref="Paragraph.InsertText(string, bool)"/>
/// <seealso cref="Paragraph.InsertText(int, string, bool)"/>
/// <seealso cref="Paragraph.InsertText(int, string, bool, Formatting)"/>
/// <seealso cref="Paragraph.InsertText(string, bool, Formatting)"/>
/// <param name="index">The position to begin deleting characters.</param>
/// <param name="count">The number of characters to delete</param>
/// <param name="trackChanges">Track changes</param>
public void RemoveText(int index, int count, bool trackChanges)
{
// Timestamp to mark the start of insert
DateTime now = DateTime.Now;
DateTime remove_datetime = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, 0, DateTimeKind.Utc);
// The number of characters processed so far
int processed = 0;
do
{
// Get the first run effected by this Remove
Run run = GetFirstRunEffectedByEdit(index + processed);
// The parent of this Run
XElement parentElement = run.xml.Parent;
switch (parentElement.Name.LocalName)
{
case "ins":
{
XElement[] splitEditBefore = SplitEdit(parentElement, index + processed, EditType.del);
int min = Math.Min(count - processed, run.xml.ElementsAfterSelf().Sum(e => GetElementTextLength(e)));
XElement[] splitEditAfter = SplitEdit(parentElement, index + processed + min, EditType.del);
XElement temp = SplitEdit(splitEditBefore[1], index + processed + min, EditType.del)[0];
object middle = CreateEdit(EditType.del, remove_datetime, temp.Elements());
processed += GetElementTextLength(middle as XElement);
if (!trackChanges)
middle = null;
parentElement.ReplaceWith
(
splitEditBefore[0],
middle,
splitEditAfter[1]
);
processed += GetElementTextLength(middle as XElement);
break;
}
case "del":
{
if (trackChanges)
{
// You cannot delete from a deletion, advance processed to the end of this del
processed += GetElementTextLength(parentElement);
}
else
goto case "ins";
break;
}
default:
{
XElement[] splitRunBefore = Run.SplitRun(run, index + processed);
int min = Math.Min(index + processed + (count - processed), run.EndIndex);
XElement[] splitRunAfter = Run.SplitRun(run, min);
object middle = CreateEdit(EditType.del, remove_datetime, new List<XElement>() { Run.SplitRun(new Run(run.StartIndex + GetElementTextLength(splitRunBefore[0]), splitRunBefore[1]), min)[0] });
processed += GetElementTextLength(middle as XElement);
if (!trackChanges)
middle = null;
run.xml.ReplaceWith
(
splitRunBefore[0],
middle,
splitRunAfter[1]
);
break;
}
}
// If after this remove the parent element is empty, remove it.
if (GetElementTextLength(parentElement) == 0)
parentElement.Remove();
}
while (processed < count);
// Rebuild the run lookup
runLookup.Clear();
BuildRunLookup(xml);
DocX.RenumberIDs();
}
/// <summary>
/// Removes characters from a Novacode.DocX.Paragraph.
/// </summary>
/// <example>
/// <code>
/// // Load the document Test.docx.
/// DocX document = DocX.Load(@"C:\Example\Test.docx");
///
/// // Iterate through the paragraphs
/// foreach (Paragraph p in document.Paragraphs)
/// {
/// // Remove all but the first 2 characters from this Paragraph.
/// p.RemoveText(2, false);
/// }
///
/// // Save changes to this document.
/// document.Close(true);
/// </code>
/// </example>
/// <seealso cref="Paragraph.ReplaceText(string, string, bool)"/>
/// <seealso cref="Paragraph.ReplaceText(string, string, bool, RegexOptions)"/>
/// <seealso cref="Paragraph.InsertText(string, bool)"/>
/// <seealso cref="Paragraph.InsertText(int, string, bool)"/>
/// <seealso cref="Paragraph.InsertText(int, string, bool, Formatting)"/>
/// <seealso cref="Paragraph.InsertText(string, bool, Formatting)"/>
/// <param name="index">The position to begin deleting characters.</param>
/// <param name="trackChanges">Track changes</param>
public void RemoveText(int index, bool trackChanges)
{
RemoveText(index, Text.Length - index, trackChanges);
}
/// <summary>
/// Replaces all occurrences of a specified System.String in this instance, with another specified System.String.
/// </summary>
/// <example>
/// <code>
/// // Load the document Test.docx.
/// DocX document = DocX.Load(@"C:\Example.docx");
///
/// // Iterate through the paragraphs in this document.
/// foreach (Paragraph p in document.Paragraphs)
/// {
/// // Replace all instances of the string "wrong" with the string "right" and ignore case.
/// p.ReplaceText("wrong", "right", false, RegexOptions.IgnoreCase);
/// }
///
/// // Save changes to this document.
/// document.Close(true);
/// </code>
/// </example>
/// <seealso cref="Paragraph.RemoveText(int, int, bool)"/>
/// <seealso cref="Paragraph.RemoveText(int, bool)"/>
/// <seealso cref="Paragraph.InsertText(string, bool)"/>
/// <seealso cref="Paragraph.InsertText(int, string, bool)"/>
/// <seealso cref="Paragraph.InsertText(int, string, bool, Formatting)"/>
/// <seealso cref="Paragraph.InsertText(string, bool, Formatting)"/>
/// <param name="newValue">A System.String to replace all occurances of oldValue.</param>
/// <param name="oldValue">A System.String to be replaced.</param>
/// <param name="options">A bitwise OR combination of RegexOption enumeration options.</param>
/// <param name="trackChanges">Track changes</param>
public void ReplaceText(string oldValue, string newValue, bool trackChanges, RegexOptions options)
{
MatchCollection mc = Regex.Matches(this.Text, Regex.Escape(oldValue), options);
// Loop through the matches in reverse order
foreach (Match m in mc.Cast<Match>().Reverse())
{
InsertText(m.Index + oldValue.Length, newValue, trackChanges);
RemoveText(m.Index, m.Length, trackChanges);
}
}
/// <summary>
/// Replaces all occurrences of a specified System.String in this instance, with another specified System.String.
/// </summary>
/// <example>
/// <code>
/// // Load the document Test.docx.
/// DocX document = DocX.Load(@"C:\Example.docx");
///
/// // Iterate through the paragraphs in this document.
/// foreach (Paragraph p in document.Paragraphs)
/// {
/// // Replace all instances of the string "wrong" with the string "right".
/// p.ReplaceText("wrong", "right", false);
/// }
///
/// // Save changes to this document.
/// document.Close(true);
/// </code>
/// </example>
/// <seealso cref="Paragraph.RemoveText(int, int, bool)"/>
/// <seealso cref="Paragraph.RemoveText(int, bool)"/>
/// <seealso cref="Paragraph.InsertText(string, bool)"/>
/// <seealso cref="Paragraph.InsertText(int, string, bool)"/>
/// <seealso cref="Paragraph.InsertText(int, string, bool, Formatting)"/>
/// <seealso cref="Paragraph.InsertText(string, bool, Formatting)"/>
/// <param name="newValue">A System.String to replace all occurances of oldValue.</param>
/// <param name="oldValue">A System.String to be replaced.</param>
/// <param name="trackChanges">Track changes</param>
public void ReplaceText(string oldValue, string newValue, bool trackChanges)
{
ReplaceText(oldValue, newValue, trackChanges, RegexOptions.None);
}
}
}

+ 0
- 389
DocX/Picture.cs 파일 보기

@@ -1,389 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Drawing;
using DocumentFormat.OpenXml.Packaging;
namespace Novacode
{
/// <summary>
/// Represents a Picture in this document, a Picture is a customized view of an Image.
/// </summary>
public class Picture
{
private string id;
private string name;
private string descr;
private int cx, cy;
private uint rotation;
private bool hFlip, vFlip;
private object pictureShape;
// The underlying XElement which this Image wraps
internal XElement i;
private XElement xfrm;
private XElement prstGeom;
/// <summary>
/// Create a new Picture.
/// </summary>
/// <param name="id">A unique id that identifies an Image embedded in this document.</param>
/// <param name="name">The name of this Picture.</param>
/// <param name="descr">The description of this Picture.</param>
public Picture(string id, string name, string descr)
{
OpenXmlPart part = DocX.mainDocumentPart.GetPartById(id);
this.id = id;
this.name = name;
this.descr = descr;
using (System.Drawing.Image img = System.Drawing.Image.FromStream(part.GetStream()))
{
this.cx = img.Width * 4156;
this.cy = img.Height * 4156;
}
XElement e = new XElement(DocX.w + "drawing");
i = XElement.Parse
(string.Format(@"
<drawing xmlns = ""http://schemas.openxmlformats.org/wordprocessingml/2006/main"">
<wp:inline distT=""0"" distB=""0"" distL=""0"" distR=""0"" xmlns:wp=""http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"">
<wp:extent cx=""{0}"" cy=""{1}"" />
<wp:effectExtent l=""0"" t=""0"" r=""0"" b=""0"" />
<wp:docPr id=""1"" name=""{3}"" descr=""{4}"" />
<wp:cNvGraphicFramePr>
<a:graphicFrameLocks xmlns:a=""http://schemas.openxmlformats.org/drawingml/2006/main"" noChangeAspect=""1"" />
</wp:cNvGraphicFramePr>
<a:graphic xmlns:a=""http://schemas.openxmlformats.org/drawingml/2006/main"">
<a:graphicData uri=""http://schemas.openxmlformats.org/drawingml/2006/picture"">
<pic:pic xmlns:pic=""http://schemas.openxmlformats.org/drawingml/2006/picture"">
<pic:nvPicPr>
<pic:cNvPr id=""0"" name=""{3}"" />
<pic:cNvPicPr />
</pic:nvPicPr>
<pic:blipFill>
<a:blip r:embed=""{2}"" xmlns:r=""http://schemas.openxmlformats.org/officeDocument/2006/relationships""/>
<a:stretch>
<a:fillRect />
</a:stretch>
</pic:blipFill>
<pic:spPr>
<a:xfrm>
<a:off x=""0"" y=""0"" />
<a:ext cx=""{0}"" cy=""{1}"" />
</a:xfrm>
<a:prstGeom prst=""rect"">
<a:avLst />
</a:prstGeom>
</pic:spPr>
</pic:pic>
</a:graphicData>
</a:graphic>
</wp:inline>
</drawing>
", cx, cy, id, name, descr));
this.xfrm =
(
from d in i.Descendants()
where d.Name.LocalName.Equals("xfrm")
select d
).Single();
this.prstGeom =
(
from d in i.Descendants()
where d.Name.LocalName.Equals("prstGeom")
select d
).Single();
this.rotation = xfrm.Attribute(XName.Get("rot")) == null ? 0 : uint.Parse(xfrm.Attribute(XName.Get("rot")).Value);
}
/// <summary>
/// Wraps an XElement as an Image
/// </summary>
/// <param name="i">The XElement i to wrap</param>
internal Picture(XElement i)
{
this.i = i;
this.id =
(
from e in i.Descendants()
where e.Name.LocalName.Equals("blip")
select e.Attribute(XName.Get("embed", "http://schemas.openxmlformats.org/officeDocument/2006/relationships")).Value
).Single();
this.name =
(
from e in i.Descendants()
let a = e.Attribute(XName.Get("name"))
where (a != null)
select a.Value
).First();
this.descr =
(
from e in i.Descendants()
let a = e.Attribute(XName.Get("descr"))
where (a != null)
select a.Value
).First();
this.cx =
(
from e in i.Descendants()
let a = e.Attribute(XName.Get("cx"))
where (a != null)
select int.Parse(a.Value)
).First();
this.cy =
(
from e in i.Descendants()
let a = e.Attribute(XName.Get("cy"))
where (a != null)
select int.Parse(a.Value)
).First();
this.xfrm =
(
from d in i.Descendants()
where d.Name.LocalName.Equals("xfrm")
select d
).Single();
this.prstGeom =
(
from d in i.Descendants()
where d.Name.LocalName.Equals("prstGeom")
select d
).Single();
this.rotation = xfrm.Attribute(XName.Get("rot")) == null ? 0 : uint.Parse(xfrm.Attribute(XName.Get("rot")).Value);
}
private void SetPictureShape(object shape)
{
this.pictureShape = shape;
XAttribute prst = prstGeom.Attribute(XName.Get("prst"));
if (prst == null)
prstGeom.Add(new XAttribute(XName.Get("prst"), "rectangle"));
prstGeom.Attribute(XName.Get("prst")).Value = shape.ToString();
}
/// <summary>
/// Set the shape of this Picture to one in the BasicShapes enumeration.
/// </summary>
/// <param name="shape">A shape from the BasicShapes enumeration.</param>
public void SetPictureShape(BasicShapes shape)
{
SetPictureShape((object)shape);
}
/// <summary>
/// Set the shape of this Picture to one in the RectangleShapes enumeration.
/// </summary>
/// <param name="shape">A shape from the RectangleShapes enumeration.</param>
public void SetPictureShape(RectangleShapes shape)
{
SetPictureShape((object)shape);
}
/// <summary>
/// Set the shape of this Picture to one in the BlockArrowShapes enumeration.
/// </summary>
/// <param name="shape">A shape from the BlockArrowShapes enumeration.</param>
public void SetPictureShape(BlockArrowShapes shape)
{
SetPictureShape((object)shape);
}
/// <summary>
/// Set the shape of this Picture to one in the EquationShapes enumeration.
/// </summary>
/// <param name="shape">A shape from the EquationShapes enumeration.</param>
public void SetPictureShape(EquationShapes shape)
{
SetPictureShape((object)shape);
}
/// <summary>
/// Set the shape of this Picture to one in the FlowchartShapes enumeration.
/// </summary>
/// <param name="shape">A shape from the FlowchartShapes enumeration.</param>
public void SetPictureShape(FlowchartShapes shape)
{
SetPictureShape((object)shape);
}
/// <summary>
/// Set the shape of this Picture to one in the StarAndBannerShapes enumeration.
/// </summary>
/// <param name="shape">A shape from the StarAndBannerShapes enumeration.</param>
public void SetPictureShape(StarAndBannerShapes shape)
{
SetPictureShape((object)shape);
}
/// <summary>
/// Set the shape of this Picture to one in the CalloutShapes enumeration.
/// </summary>
/// <param name="shape">A shape from the CalloutShapes enumeration.</param>
public void SetPictureShape(CalloutShapes shape)
{
SetPictureShape((object)shape);
}
/// <summary>
/// A unique id that identifies an Image embedded in this document.
/// </summary>
public string Id
{
get { return id; }
}
/// <summary>
/// Flip this Picture Horizontally.
/// </summary>
public bool FlipHorizontal
{
get { return hFlip; }
set
{
hFlip = value;
XAttribute flipH = xfrm.Attribute(XName.Get("flipH"));
if (flipH == null)
xfrm.Add(new XAttribute(XName.Get("flipH"), "0"));
xfrm.Attribute(XName.Get("flipH")).Value = hFlip ? "1" : "0";
}
}
/// <summary>
/// Flip this Picture Vertically.
/// </summary>
public bool FlipVertical
{
get { return vFlip; }
set
{
vFlip = value;
XAttribute flipV = xfrm.Attribute(XName.Get("flipV"));
if (flipV == null)
xfrm.Add(new XAttribute(XName.Get("flipV"), "0"));
xfrm.Attribute(XName.Get("flipV")).Value = vFlip ? "1" : "0";
}
}
/// <summary>
/// The rotation in degrees of this image, actual value = value % 360
/// </summary>
public uint Rotation
{
get { return rotation / 60000; }
set
{
rotation = (value % 360) * 60000;
XElement xfrm =
(from d in i.Descendants()
where d.Name.LocalName.Equals("xfrm")
select d).Single();
XAttribute rot = xfrm.Attribute(XName.Get("rot"));
if(rot == null)
xfrm.Add(new XAttribute(XName.Get("rot"), 0));
xfrm.Attribute(XName.Get("rot")).Value = rotation.ToString();
}
}
/// <summary>
/// Gets or sets the name of this Image.
/// </summary>
public string Name
{
get { return name; }
set
{
name = value;
foreach (XAttribute a in i.Descendants().Attributes(XName.Get("name")))
a.Value = name;
}
}
/// <summary>
/// Gets or sets the description for this Image.
/// </summary>
public string Description
{
get { return descr; }
set
{
descr = value;
foreach (XAttribute a in i.Descendants().Attributes(XName.Get("descr")))
a.Value = descr;
}
}
/// <summary>
/// Get or sets the Width of this Image.
/// </summary>
public int Width
{
get { return cx / 4156; }
set
{
cx = value;
foreach (XAttribute a in i.Descendants().Attributes(XName.Get("cx")))
a.Value = (cx * 4156).ToString();
}
}
/// <summary>
/// Get or sets the height of this Image.
/// </summary>
public int Height
{
get { return cy / 4156; }
set
{
cy = value;
foreach (XAttribute a in i.Descendants().Attributes(XName.Get("cy")))
a.Value = (cy * 4156).ToString();
}
}
//public void Delete()
//{
// // Remove xml
// i.Remove();
// // Rebuild the image collection for this paragraph
// // Requires that every Image have a link to its paragraph
//}
}
}

+ 0
- 36
DocX/Properties/AssemblyInfo.cs 파일 보기

@@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Docx")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("Docx")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2008")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("16123f21-f3d1-47bb-ae9a-eb7c82c0f3c8")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.4")]
[assembly: AssemblyFileVersion("1.0.0.4")]

+ 0
- 119
DocX/Run.cs 파일 보기

@@ -1,119 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace Novacode
{
internal class Run
{
// A lookup for the text elements in this paragraph
Dictionary<int, Text> textLookup = new Dictionary<int, Text>();
private int startIndex;
private int endIndex;
private string text;
internal XElement xml;
/// <summary>
/// Gets the start index of this Text (text length before this text)
/// </summary>
public int StartIndex { get { return startIndex; } }
/// <summary>
/// Gets the end index of this Text (text length before this text + this texts length)
/// </summary>
public int EndIndex { get { return endIndex; } }
/// <summary>
/// The text value of this text element
/// </summary>
private string Value { set { value = text; } get { return text; } }
internal Run(int startIndex, XElement xml)
{
this.startIndex = startIndex;
this.xml = xml;
// Get the text elements in this run
IEnumerable<XElement> texts = xml.Descendants();
int start = startIndex;
// Loop through each text in this run
foreach (XElement te in texts)
{
switch (te.Name.LocalName)
{
case "tab":
{
textLookup.Add(start + 1, new Text(start, te));
text += "\t";
start++;
break;
}
case "br":
{
textLookup.Add(start + 1, new Text(start, te));
text += "\n";
start++;
break;
}
case "t": goto case "delText";
case "delText":
{
// Only add strings which are not empty
if (te.Value.Length > 0)
{
textLookup.Add(start + te.Value.Length, new Text(start, te));
text += te.Value;
start += te.Value.Length;
}
break;
}
default: break;
}
}
endIndex = start;
}
static internal XElement[] SplitRun(Run r, int index)
{
Text t = r.GetFirstTextEffectedByEdit(index);
XElement[] splitText = Text.SplitText(t, index);
XElement splitLeft = new XElement(r.xml.Name, r.xml.Attributes(), r.xml.Element(XName.Get("rPr", DocX.w.NamespaceName)), t.xml.ElementsBeforeSelf().Where(n => n.Name.LocalName != "rPr"), splitText[0]);
if(Paragraph.GetElementTextLength(splitLeft) == 0)
splitLeft = null;
XElement splitRight = new XElement(r.xml.Name, r.xml.Attributes(), r.xml.Element(XName.Get("rPr", DocX.w.NamespaceName)), splitText[1], t.xml.ElementsAfterSelf().Where(n => n.Name.LocalName != "rPr"));
if(Paragraph.GetElementTextLength(splitRight) == 0)
splitRight = null;
return
(
new XElement[]
{
splitLeft,
splitRight
}
);
}
internal Text GetFirstTextEffectedByEdit(int index)
{
foreach (int textEndIndex in textLookup.Keys)
{
if (textEndIndex > index)
return textLookup[textEndIndex];
}
if (textLookup.Last().Value.EndIndex == index)
return textLookup.Last().Value;
throw new ArgumentOutOfRangeException();
}
}
}

+ 0
- 143
DocX/Text.cs 파일 보기

@@ -1,143 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace Novacode
{
internal class Text
{
private int startIndex;
private int endIndex;
private string text;
internal XElement xml;
/// <summary>
/// Gets the start index of this Text (text length before this text)
/// </summary>
public int StartIndex { get { return startIndex; } }
/// <summary>
/// Gets the end index of this Text (text length before this text + this texts length)
/// </summary>
public int EndIndex { get { return endIndex; } }
/// <summary>
/// The text value of this text element
/// </summary>
public string Value { get { return text; } }
internal Text(int startIndex, XElement e)
{
this.startIndex = startIndex;
this.xml = e;
switch (e.Name.LocalName)
{
case "t":
{
goto case "delText";
}
case "delText":
{
endIndex = startIndex + e.Value.Length;
text = e.Value;
break;
}
case "br":
{
text = "\n";
endIndex = startIndex + 1;
break;
}
case "tab":
{
text = "\t";
endIndex = startIndex + 1;
break;
}
default:
{
break;
}
}
}
internal static XElement[] SplitText(Text t, int index)
{
if (index < t.startIndex || index > t.EndIndex)
throw new ArgumentOutOfRangeException("index");
XElement splitLeft = null, splitRight = null;
if (t.xml.Name.LocalName == "t" || t.xml.Name.LocalName == "delText")
{
// The origional text element, now containing only the text before the index point.
splitLeft = new XElement(t.xml.Name, t.xml.Attributes(), t.xml.Value.Substring(0, index - t.startIndex));
if (splitLeft.Value.Length == 0)
splitLeft = null;
else
PreserveSpace(splitLeft);
// The origional text element, now containing only the text after the index point.
splitRight = new XElement(t.xml.Name, t.xml.Attributes(), t.xml.Value.Substring(index - t.startIndex, t.xml.Value.Length - (index - t.startIndex)));
if (splitRight.Value.Length == 0)
splitRight = null;
else
PreserveSpace(splitRight);
}
else
{
if (index == t.StartIndex)
splitLeft = t.xml;
else
splitRight = t.xml;
}
return
(
new XElement[]
{
splitLeft,
splitRight
}
);
}
/// <summary>
/// If a text element or delText element, starts or ends with a space,
/// it must have the attribute space, otherwise it must not have it.
/// </summary>
/// <param name="e">The (t or delText) element check</param>
public static void PreserveSpace(XElement e)
{
// PreserveSpace should only be used on (t or delText) elements
if (!e.Name.Equals(DocX.w + "t") && !e.Name.Equals(DocX.w + "delText"))
throw new ArgumentException("SplitText can only split elements of type t or delText", "e");
// Check if this w:t contains a space atribute
XAttribute space = e.Attributes().Where(a => a.Name.Equals(XNamespace.Xml + "space")).SingleOrDefault();
// This w:t's text begins or ends with whitespace
if (e.Value.StartsWith(" ") || e.Value.EndsWith(" "))
{
// If this w:t contains no space attribute, add one.
if (space == null)
e.Add(new XAttribute(XNamespace.Xml + "space", "preserve"));
}
// This w:t's text does not begin or end with a space
else
{
// If this w:r contains a space attribute, remove it.
if (space != null)
space.Remove();
}
}
}
}

+ 0
- 4
DocX/app.config 파일 보기

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
</configuration>

Loading…
취소
저장