浏览代码

Fixed some minor bugs. Added the ability to create .docx files on the fly, and to insert text with custom formatting.

master
coffeycathal_cp 17 年前
父节点
当前提交
f25cfc2ef9

+ 6
- 4
CustomPropertyTestApp/CustomPropertyTestApp.csproj 查看文件

@@ -35,10 +35,6 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="DocX, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\DocX\bin\Debug\DocX.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
@@ -61,6 +57,12 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DocX\DocX.csproj">
<Project>{E863D072-AA8B-4108-B5F1-785241B37F67}</Project>
<Name>DocX</Name>
</ProjectReference>
</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.

+ 6
- 0
DocX.sln 查看文件

@@ -19,6 +19,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StringReplaceTestApp", "Str
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CustomPropertyTestApp", "CustomPropertyTestApp\CustomPropertyTestApp.csproj", "{9EABCAA8-175C-4FA2-9829-59E9D9E275D3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CreateDocumentOnTheFly", "CreateDocumentOnTheFly\CreateDocumentOnTheFly.csproj", "{40E089B2-BFE4-4E47-83CC-36A4D43269C4}"
EndProject
Global
GlobalSection(TeamFoundationVersionControl) = preSolution
SccNumberOfProjects = 5
@@ -62,6 +64,10 @@ Global
{9EABCAA8-175C-4FA2-9829-59E9D9E275D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9EABCAA8-175C-4FA2-9829-59E9D9E275D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9EABCAA8-175C-4FA2-9829-59E9D9E275D3}.Release|Any CPU.Build.0 = Release|Any CPU
{40E089B2-BFE4-4E47-83CC-36A4D43269C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{40E089B2-BFE4-4E47-83CC-36A4D43269C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{40E089B2-BFE4-4E47-83CC-36A4D43269C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{40E089B2-BFE4-4E47-83CC-36A4D43269C4}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

+ 79
- 1
DocX/DocX.cs 查看文件

@@ -97,6 +97,84 @@ namespace Novacode
get { return customProperties; }
}
public Paragraph AddParagraph()
{
XElement newParagraph = new XElement(w + "p");
mainDoc.Descendants(XName.Get("body", "http://schemas.openxmlformats.org/wordprocessingml/2006/main")).Single().Add(newParagraph);
// Get all of the paragraphs in this document
DocX.paragraphs = from p in mainDoc.Descendants(XName.Get("p", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"))
select new Paragraph(p);
return new Paragraph(newParagraph);
}
public static DocX Create(string uri)
{
FileInfo fi = new FileInfo(uri);
if (fi.Extension != ".docx")
throw new Exception(string.Format("The input file {0} is not a .docx file", fi.FullName));
DocX.uri = uri;
// Create the docx package
wdDoc = WordprocessingDocument.Create(uri, DocumentFormat.OpenXml.WordprocessingDocumentType.Document);
#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>"
);
}
// Get all of the paragraphs in this document
DocX.paragraphs = from p in mainDoc.Descendants(XName.Get("p", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"))
select new Paragraph(p);
#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);
}
#endregion
// Save the new docx file to disk and return
DocX created = new DocX();
created.Save();
return created;
}
/// <summary>
/// Loads a .docx file into a DocX object.
/// </summary>
@@ -390,7 +468,7 @@ namespace Novacode
/// <summary>
/// Renumber all ins and del ids in this .docx file.
/// </summary>
private static void RenumberIDs()
internal static void RenumberIDs()
{
IEnumerable<XAttribute> trackerIDs =
(from d in mainDoc.Descendants()

+ 6
- 0
DocX/DocX.csproj 查看文件

@@ -43,6 +43,7 @@
<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>
@@ -51,10 +52,15 @@
<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="Paragraph.cs" />
<Compile Include="DocX.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />

+ 32
- 0
DocX/Extensions.cs 查看文件

@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
namespace Novacode
{
public static class Extensions
{
public 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);
}
}
}

+ 272
- 0
DocX/Formatting.cs 查看文件

@@ -0,0 +1,272 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Drawing;
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 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;
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));
}
public 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;
}
}
public bool Bold { get { return bold; } set { bold = value;} }
public bool Italic { get { return Italic; } set { italic = value; } }
public StrickThrough StrikeThrough { get { return strikethrough; } set { strikethrough = value; } }
public Script Script { get { return script; } set { script = value; } }
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");
}
}
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");
}
}
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");
}
}
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");
}
}
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");
}
}
public Color? FontColor { get { return fontColor; } set { fontColor = value; } }
public Highlight Highlight { get { return highlight; } set { highlight = value; } }
public UnderlineStyle UnderlineStyle { get { return underlineStyle; } set { underlineStyle = value; } }
public Color? UnderlineColor { get { return underlineColor; } set { underlineColor = value; } }
public Misc Misc { get { return misc; } set { misc = value; } }
public bool Hidden { get { return hidden; } set { hidden = value; } }
public CapsStyle CapsStyle { get { return capsStyle; } set { capsStyle = value; } }
public FontFamily FontFamily { get { return FontFamily; } set { fontFamily = value; } }
}
}

+ 102
- 67
DocX/Paragraph.cs 查看文件

@@ -42,9 +42,13 @@ namespace Novacode
// Loop through each run in this paragraph
foreach (XElement run in runs)
{
Run r = new Run(startIndex, run);
runLookup.Add(r.EndIndex, r);
startIndex = r.EndIndex;
// Only add runs which contain text
if (GetElementTextLength(run) > 0)
{
Run r = new Run(startIndex, run);
runLookup.Add(r.EndIndex, r);
startIndex = r.EndIndex;
}
}
}
@@ -149,6 +153,10 @@ namespace Novacode
/// <returns>The first Run that will be effected</returns>
public 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)
@@ -267,6 +275,11 @@ namespace Novacode
);
}
public void Insert(int index, string value, bool trackChanges)
{
Insert(index, value, null, trackChanges);
}
/// <summary>
/// Inserts a specified instance of System.String into a Novacode.DocX.Paragraph at a specified index position.
/// </summary>
@@ -311,7 +324,7 @@ namespace Novacode
/// <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 Insert(int index, string value, bool trackChanges)
public void Insert(int index, string value, Formatting formatting, bool trackChanges)
{
// Timestamp to mark the start of insert
DateTime now = DateTime.Now;
@@ -320,82 +333,102 @@ namespace Novacode
// Get the first run effected by this Insert
Run run = GetFirstRunEffectedByInsert(index);
// Convert value into a List of XElement's
List<XElement> newRuns = formatInput(value, run.Xml.Element(XName.Get("rPr", DocX.w.NamespaceName)));
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);
p.Add(insert);
}
// The parent of this Run
XElement parentElement = run.Xml.Parent;
switch (parentElement.Name.LocalName)
else
{
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)
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;
}
/*
* Inserting into a non edit and this special case, is the same procedure.
* If not the special case above,
* then inserting into an ins or a del, is the same procedure.
*/
goto default;
goto case "del";
}
/*
* 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);
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;
}
// Split this Edit at the point you want to insert
XElement[] splitEdit = SplitEdit(parentElement, index, EditType.ins);
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;
}
// 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(p);
DocX.RenumberIDs();
}
/// <summary>
@@ -446,7 +479,8 @@ namespace Novacode
int min = Math.Min(count - processed, run.Xml.ElementsAfterSelf().Sum(e => GetElementTextLength(e)));
XElement[] splitEditAfter = SplitEdit(parentElement, index + processed + min, EditType.del);
object middle = CreateEdit(EditType.del, remove_datetime, SplitEdit(splitEditBefore[1], min, EditType.del)[0].Descendants());
XElement temp = SplitEdit(splitEditBefore[1], index + processed + min, EditType.del)[0];
object middle = CreateEdit(EditType.del, remove_datetime, temp.Elements().ToArray());
processed += GetElementTextLength(middle as XElement);
if (!trackChanges)
@@ -509,6 +543,7 @@ namespace Novacode
// Rebuild the run lookup
runLookup.Clear();
BuildRunLookup(p);
DocX.RenumberIDs();
}
/// <summary>

+ 7
- 3
DocX/Run.cs 查看文件

@@ -75,9 +75,13 @@ namespace Novacode
case "t": goto case "delText";
case "delText":
{
textLookup.Add(start + text.Value.Length, new Text(start, text));
Value += text.Value;
start += text.Value.Length;
// Only add strings which are not empty
if (text.Value.Length > 0)
{
textLookup.Add(start + text.Value.Length, new Text(start, text));
Value += text.Value;
start += text.Value.Length;
}
break;
}
default: break;

+ 1
- 0
StringReplaceTestApp/Program.cs 查看文件

@@ -5,6 +5,7 @@ using System.Text;
using Novacode;
using System.Text.RegularExpressions;
using System.IO;
using System.Xml.Linq;
namespace StringReplaceTestApp
{

+ 6
- 4
StringReplaceTestApp/StringReplaceTestApp.csproj 查看文件

@@ -35,10 +35,6 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="DocX, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\DocX\bin\Debug\DocX.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
@@ -61,6 +57,12 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DocX\DocX.csproj">
<Project>{E863D072-AA8B-4108-B5F1-785241B37F67}</Project>
<Name>DocX</Name>
</ProjectReference>
</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.

正在加载...
取消
保存