Просмотр исходного кода

Added basic support for PageNumber and PageCount place holders.

When inserted into a Header or Footer Word will automatically display the correct value foreach page.

Word will not automatically update these place holders if inserted inside a document level Paragraph. 
You need to right click and select update field. I therefore suggest that you only use these place holders inside Headers and Footers.

Added
-------

Paragraph.AppendPageNumber(PageNumberFormat)
Paragraph.InsertPageNumber(PageNumberFormat, int index)

Paragraph.AppendPageCount(PageNumberFormat)
Paragraph.InsertPageCount(PageNumberFormat, int index)

Example
-----------
// Create a new document.
using (DocX document = DocX.Create(@"Test.docx"))
{
    // Add Headers to the document.
    document.AddHeaders();

    // Get the default Header.
    Header header = document.Headers.odd;

    // Insert a Paragraph into the Header.
    Paragraph p0 = header.InsertParagraph();

    // Append place holders for PageNumber and PageCount into the Header.
    // Word will replace these with the correct value foreach Page.
    p0.Append("Page (");
    p0.AppendPageNumber(PageNumberFormat.normal);
    p0.Append(" of ");
    p0.AppendPageCount(PageNumberFormat.normal);
    p0.Append(")");

    // Save the document.
    document.Save();
}
master
coffeycathal_cp 15 лет назад
Родитель
Сommit
68351622e7
6 измененных файлов: 454 добавлений и 10 удалений
  1. 4
    0
      DocX/Container.cs
  2. 88
    1
      DocX/DocX.cs
  3. 41
    0
      DocX/Footer.cs
  4. 45
    0
      DocX/Header.cs
  5. 270
    9
      DocX/Paragraph.cs
  6. 6
    0
      DocX/_Enumerations.cs

+ 4
- 0
DocX/Container.cs Просмотреть файл

@@ -86,6 +86,10 @@ namespace Novacode
internal void GetParagraphsRecursive(XElement Xml, ref int index, ref List<Paragraph> paragraphs)
{
// sdtContent are for PageNumbers inside Headers or Footers, don't go any deeper.
if (Xml.Name.LocalName == "sdtContent")
return;
if (Xml.Name.LocalName == "p")
{
paragraphs.Add(new Paragraph(Document, Xml, index));

+ 88
- 1
DocX/DocX.cs Просмотреть файл

@@ -27,6 +27,27 @@ namespace Novacode
static internal XNamespace customVTypesSchema = "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes";
#endregion
/// <summary>
/// Returns true if any editing restrictions are imposed on this document.
/// </summary>
/// <example>
/// <code>
/// // Create a new document.
/// using (DocX document = DocX.Create(@"Test.docx"))
/// {
/// if(document.isProtected)
/// Console.WriteLine("Protected");
/// else
/// Console.WriteLine("Not protected");
///
/// // Save the document.
/// document.Save();
/// }
/// </code>
/// </example>
/// <seealso cref="AddProtection"/>
/// <seealso cref="RemoveProtection"/>
/// <seealso cref="GetProtectionType"/>
public bool isProtected
{
get
@@ -35,6 +56,33 @@ namespace Novacode
}
}
/// <summary>
/// Returns the type of editing protection imposed on this document.
/// </summary>
/// <returns>The type of editing protection imposed on this document.</returns>
/// <example>
/// <code>
/// Create a new document.
/// using (DocX document = DocX.Create(@"Test.docx"))
/// {
/// // Make sure the document is protected before checking the protection type.
/// if (document.isProtected)
/// {
/// EditRestrictions protection = document.GetProtectionType();
/// Console.WriteLine("Document is protected using " + protection.ToString());
/// }
///
/// else
/// Console.WriteLine("Document is not protected.");
///
/// // Save the document.
/// document.Save();
/// }
/// </code>
/// </example>
/// <seealso cref="AddProtection"/>
/// <seealso cref="RemoveProtection"/>
/// <seealso cref="isProtected"/>
public EditRestrictions GetProtectionType()
{
if (isProtected)
@@ -47,6 +95,26 @@ namespace Novacode
return EditRestrictions.none;
}
/// <summary>
/// Add editing protection to this document.
/// </summary>
/// <param name="er">The type of protection to add to this document.</param>
/// <example>
/// <code>
/// // Create a new document.
/// using (DocX document = DocX.Create(@"Test.docx"))
/// {
/// // Allow no editing, only the adding of comment.
/// document.AddProtection(EditRestrictions.comments);
///
/// // Save the document.
/// document.Save();
/// }
/// </code>
/// </example>
/// <seealso cref="RemoveProtection"/>
/// <seealso cref="GetProtectionType"/>
/// <seealso cref="isProtected"/>
public void AddProtection(EditRestrictions er)
{
// Call remove protection before adding a new protection element.
@@ -61,7 +129,26 @@ namespace Novacode
settings.Root.AddFirst(documentProtection);
}
/// <summary>
/// Remove editing protection from this document.
/// </summary>
/// <example>
/// <code>
/// // Create a new document.
/// using (DocX document = DocX.Create(@"Test.docx"))
/// {
/// // Remove any editing restrictions that are imposed on this document.
/// document.RemoveProtection();
///
/// // Save the document.
/// document.Save();
/// }
/// </code>
/// </example>
/// <seealso cref="AddProtection"/>
/// <seealso cref="GetProtectionType"/>
/// <seealso cref="isProtected"/>
public void RemoveProtection()
{
// Remove every node of type documentProtection.

+ 41
- 0
DocX/Footer.cs Просмотреть файл

@@ -9,6 +9,47 @@ namespace Novacode
{
public class Footer : Container
{
public bool PageNumbers
{
get
{
return false;
}
set
{
XElement e = XElement.Parse
(@"<w:sdt xmlns:w='http://schemas.openxmlformats.org/wordprocessingml/2006/main'>
<w:sdtPr>
<w:id w:val='157571950' />
<w:docPartObj>
<w:docPartGallery w:val='Page Numbers (Top of Page)' />
<w:docPartUnique />
</w:docPartObj>
</w:sdtPr>
<w:sdtContent>
<w:p w:rsidR='008D2BFB' w:rsidRDefault='008D2BFB'>
<w:pPr>
<w:pStyle w:val='Header' />
<w:jc w:val='center' />
</w:pPr>
<w:fldSimple w:instr=' PAGE \* MERGEFORMAT'>
<w:r>
<w:rPr>
<w:noProof />
</w:rPr>
<w:t>1</w:t>
</w:r>
</w:fldSimple>
</w:p>
</w:sdtContent>
</w:sdt>"
);
Xml.AddFirst(e);
}
}
internal PackagePart mainPart;
internal Footer(DocX document, XElement xml, PackagePart mainPart): base(document, xml)
{

+ 45
- 0
DocX/Header.cs Просмотреть файл

@@ -9,6 +9,51 @@ namespace Novacode
{
public class Header : Container
{
public bool PageNumbers
{
get
{
return false;
}
set
{
XElement e = XElement.Parse
(@"<w:sdt xmlns:w='http://schemas.openxmlformats.org/wordprocessingml/2006/main'>
<w:sdtPr>
<w:id w:val='157571950' />
<w:docPartObj>
<w:docPartGallery w:val='Page Numbers (Top of Page)' />
<w:docPartUnique />
</w:docPartObj>
</w:sdtPr>
<w:sdtContent>
<w:p w:rsidR='008D2BFB' w:rsidRDefault='008D2BFB'>
<w:pPr>
<w:pStyle w:val='Header' />
<w:jc w:val='center' />
</w:pPr>
<w:fldSimple w:instr=' PAGE \* MERGEFORMAT'>
<w:r>
<w:rPr>
<w:noProof />
</w:rPr>
<w:t>1</w:t>
</w:r>
</w:fldSimple>
</w:p>
</w:sdtContent>
</w:sdt>"
);
Xml.AddFirst(e);
PageNumberParagraph = new Paragraph(Document, e.Descendants(XName.Get("p", DocX.w.NamespaceName)).SingleOrDefault(), 0);
}
}
public Paragraph PageNumberParagraph;
internal PackagePart mainPart;
internal Header(DocX document, XElement xml, PackagePart mainPart):base(document, xml)
{

+ 270
- 9
DocX/Paragraph.cs Просмотреть файл

@@ -1789,16 +1789,23 @@ namespace Novacode
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);
// Special case to deal with Page Number elements.
if (parentElement.Name.LocalName.Equals("fldSimple"))
parentElement.AddBeforeSelf(insert);
// Replace the origional run
run.Xml.ReplaceWith
(
splitRun[0],
insert,
splitRun[1]
);
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],
insert,
splitRun[1]
);
}
break;
}
@@ -3162,6 +3169,260 @@ namespace Novacode
return query;
}
/// <summary>
/// Insert a PageNumber place holder into a Paragraph.
/// This place holder should only be inserted into a Header or Footer Paragraph.
/// Word will not automatically update this field if it is inserted into a document level Paragraph.
/// </summary>
/// <param name="pnf">The PageNumberFormat can be normal: (1, 2, ...) or Roman: (I, II, ...)</param>
/// <param name="index">The text index to insert this PageNumber place holder at.</param>
/// <example>
/// <code>
/// // Create a new document.
/// using (DocX document = DocX.Create(@"Test.docx"))
/// {
/// // Add Headers to the document.
/// document.AddHeaders();
///
/// // Get the default Header.
/// Header header = document.Headers.odd;
///
/// // Insert a Paragraph into the Header.
/// Paragraph p0 = header.InsertParagraph("Page ( of )");
///
/// // Insert place holders for PageNumber and PageCount into the Header.
/// // Word will replace these with the correct value for each Page.
/// p0.InsertPageNumber(PageNumberFormat.normal, 6);
/// p0.InsertPageCount(PageNumberFormat.normal, 11);
///
/// // Save the document.
/// document.Save();
/// }
/// </code>
/// </example>
/// <seealso cref="AppendPageCount"/>
/// <seealso cref="AppendPageNumber"/>
/// <seealso cref="InsertPageCount"/>
public void InsertPageNumber(PageNumberFormat pnf, int index = 0)
{
XElement fldSimple = new XElement(XName.Get("fldSimple", DocX.w.NamespaceName));
if (pnf == PageNumberFormat.normal)
fldSimple.Add(new XAttribute(XName.Get("instr", DocX.w.NamespaceName), @" PAGE \* MERGEFORMAT "));
else
fldSimple.Add(new XAttribute(XName.Get("instr", DocX.w.NamespaceName), @" PAGE \* ROMAN \* MERGEFORMAT "));
XElement content = XElement.Parse
(
@"<w:r w:rsidR='001D0226' xmlns:w=""http://schemas.openxmlformats.org/wordprocessingml/2006/main"">
<w:rPr>
<w:noProof />
</w:rPr>
<w:t>1</w:t>
</w:r>"
);
fldSimple.Add(content);
if (index == 0)
Xml.AddFirst(fldSimple);
else
{
Run r = GetFirstRunEffectedByEdit(index, EditType.ins);
XElement[] splitEdit = SplitEdit(r.Xml, index, EditType.ins);
r.Xml.ReplaceWith
(
splitEdit[0],
fldSimple,
splitEdit[1]
);
}
}
/// <summary>
/// Append a PageNumber place holder onto the end of a Paragraph.
/// </summary>
/// <param name="pnf">The PageNumberFormat can be normal: (1, 2, ...) or Roman: (I, II, ...)</param>
/// <example>
/// <code>
/// // Create a new document.
/// using (DocX document = DocX.Create(@"Test.docx"))
/// {
/// // Add Headers to the document.
/// document.AddHeaders();
///
/// // Get the default Header.
/// Header header = document.Headers.odd;
///
/// // Insert a Paragraph into the Header.
/// Paragraph p0 = header.InsertParagraph();
///
/// // Appemd place holders for PageNumber and PageCount into the Header.
/// // Word will replace these with the correct value for each Page.
/// p0.Append("Page (");
/// p0.AppendPageNumber(PageNumberFormat.normal);
/// p0.Append(" of ");
/// p0.AppendPageCount(PageNumberFormat.normal);
/// p0.Append(")");
///
/// // Save the document.
/// document.Save();
/// }
/// </code>
/// </example>
/// <seealso cref="AppendPageCount"/>
/// <seealso cref="InsertPageNumber"/>
/// <seealso cref="InsertPageCount"/>
public void AppendPageNumber(PageNumberFormat pnf)
{
XElement fldSimple = new XElement(XName.Get("fldSimple", DocX.w.NamespaceName));
if(pnf == PageNumberFormat.normal)
fldSimple.Add(new XAttribute(XName.Get("instr", DocX.w.NamespaceName), @" PAGE \* MERGEFORMAT "));
else
fldSimple.Add(new XAttribute(XName.Get("instr", DocX.w.NamespaceName), @" PAGE \* ROMAN \* MERGEFORMAT "));
XElement content = XElement.Parse
(
@"<w:r w:rsidR='001D0226' xmlns:w=""http://schemas.openxmlformats.org/wordprocessingml/2006/main"">
<w:rPr>
<w:noProof />
</w:rPr>
<w:t>1</w:t>
</w:r>"
);
fldSimple.Add(content);
Xml.Add(fldSimple);
}
/// <summary>
/// Insert a PageCount place holder into a Paragraph.
/// This place holder should only be inserted into a Header or Footer Paragraph.
/// Word will not automatically update this field if it is inserted into a document level Paragraph.
/// </summary>
/// <param name="pnf">The PageNumberFormat can be normal: (1, 2, ...) or Roman: (I, II, ...)</param>
/// <param name="index">The text index to insert this PageCount place holder at.</param>
/// <example>
/// <code>
/// // Create a new document.
/// using (DocX document = DocX.Create(@"Test.docx"))
/// {
/// // Add Headers to the document.
/// document.AddHeaders();
///
/// // Get the default Header.
/// Header header = document.Headers.odd;
///
/// // Insert a Paragraph into the Header.
/// Paragraph p0 = header.InsertParagraph("Page ( of )");
///
/// // Insert place holders for PageNumber and PageCount into the Header.
/// // Word will replace these with the correct value for each Page.
/// p0.InsertPageNumber(PageNumberFormat.normal, 6);
/// p0.InsertPageCount(PageNumberFormat.normal, 11);
///
/// // Save the document.
/// document.Save();
/// }
/// </code>
/// </example>
/// <seealso cref="AppendPageCount"/>
/// <seealso cref="AppendPageNumber"/>
/// <seealso cref="InsertPageNumber"/>
public void InsertPageCount(PageNumberFormat pnf, int index = 0)
{
XElement fldSimple = new XElement(XName.Get("fldSimple", DocX.w.NamespaceName));
if (pnf == PageNumberFormat.normal)
fldSimple.Add(new XAttribute(XName.Get("instr", DocX.w.NamespaceName), @" NUMPAGES \* MERGEFORMAT "));
else
fldSimple.Add(new XAttribute(XName.Get("instr", DocX.w.NamespaceName), @" NUMPAGES \* ROMAN \* MERGEFORMAT "));
XElement content = XElement.Parse
(
@"<w:r w:rsidR='001D0226' xmlns:w=""http://schemas.openxmlformats.org/wordprocessingml/2006/main"">
<w:rPr>
<w:noProof />
</w:rPr>
<w:t>1</w:t>
</w:r>"
);
fldSimple.Add(content);
if (index == 0)
Xml.AddFirst(fldSimple);
else
{
Run r = GetFirstRunEffectedByEdit(index, EditType.ins);
XElement[] splitEdit = SplitEdit(r.Xml, index, EditType.ins);
r.Xml.ReplaceWith
(
splitEdit[0],
fldSimple,
splitEdit[1]
);
}
}
/// <summary>
/// Append a PageCount place holder onto the end of a Paragraph.
/// </summary>
/// <param name="pnf">The PageNumberFormat can be normal: (1, 2, ...) or Roman: (I, II, ...)</param>
/// <example>
/// <code>
/// // Create a new document.
/// using (DocX document = DocX.Create(@"Test.docx"))
/// {
/// // Add Headers to the document.
/// document.AddHeaders();
///
/// // Get the default Header.
/// Header header = document.Headers.odd;
///
/// // Insert a Paragraph into the Header.
/// Paragraph p0 = header.InsertParagraph();
///
/// // Appemd place holders for PageNumber and PageCount into the Header.
/// // Word will replace these with the correct value for each Page.
/// p0.Append("Page (");
/// p0.AppendPageNumber(PageNumberFormat.normal);
/// p0.Append(" of ");
/// p0.AppendPageCount(PageNumberFormat.normal);
/// p0.Append(")");
///
/// // Save the document.
/// document.Save();
/// }
/// </code>
/// </example>
/// <seealso cref="AppendPageNumber"/>
/// <seealso cref="InsertPageNumber"/>
/// <seealso cref="InsertPageCount"/>
public void AppendPageCount(PageNumberFormat pnf)
{
XElement fldSimple = new XElement(XName.Get("fldSimple", DocX.w.NamespaceName));
if (pnf == PageNumberFormat.normal)
fldSimple.Add(new XAttribute(XName.Get("instr", DocX.w.NamespaceName), @" NUMPAGES \* MERGEFORMAT "));
else
fldSimple.Add(new XAttribute(XName.Get("instr", DocX.w.NamespaceName), @" NUMPAGES \* ROMAN \* MERGEFORMAT "));
XElement content = XElement.Parse
(
@"<w:r w:rsidR='001D0226' xmlns:w=""http://schemas.openxmlformats.org/wordprocessingml/2006/main"">
<w:rPr>
<w:noProof />
</w:rPr>
<w:t>1</w:t>
</w:r>"
);
fldSimple.Add(content);
Xml.Add(fldSimple);
}
}
public class Run : DocXElement

+ 6
- 0
DocX/_Enumerations.cs Просмотреть файл

@@ -5,6 +5,12 @@ using System.Text;
namespace Novacode
{
public enum PageNumberFormat
{
normal,
roman
}
public enum BorderSize
{
one,

Загрузка…
Отмена
Сохранить