├── .gitattributes ├── .gitignore ├── ConsoleApplication1 ├── App.config ├── Console_NET471.csproj ├── Program.cs ├── Properties │ └── AssemblyInfo.cs ├── packages.config └── purple.png ├── DocX.sln ├── README.md ├── pack.txt └── src ├── DocX.ConsoleTest ├── DocX.ConsoleTest.csproj ├── Program.cs └── purple.png ├── DocX.UnitTest ├── AppendBookmark.cs ├── DocX.UnitTest.csproj ├── DocXUnitTests.cs ├── InsertAtBookmark.cs ├── Properties │ └── AssemblyInfo.cs ├── RelativeDirectory.cs ├── ReplaceTests.cs ├── TestHelper.cs └── documents │ ├── ..svnbridge │ └── Template.dotx │ ├── EverybodyHasAHome.docx │ ├── FontFormat.docx │ ├── Hyperlinks.docx │ ├── Images.docx │ ├── LargeTable.docx │ ├── MovePicture.docx │ ├── Paragraphs.docx │ ├── ReplaceTests.docx │ ├── TableSpecifiedWidths.docx │ ├── Tables.docx │ ├── Template.dotx │ ├── TestParent.docx │ ├── VariousTextFormatting - Kopie.docx.zip │ ├── VariousTextFormatting.docx │ ├── green.jpg │ ├── orange.gif │ ├── purple.png │ ├── red.bmp │ ├── testdoc_OrderedList.docx │ ├── testdoc_OrderedUnorderedLists.docx │ ├── testdoc_SectionsWithHeadingBreaks.docx │ ├── testdoc_SectionsWithSectionBreaks.docx │ ├── testdoc_SectionsWithSectionBreaksMultiParagraph.docx │ ├── testdoc_UnorderedList.docx │ └── yellow.tif └── DocXCore ├── Bookmark.cs ├── BookmarkCollection.cs ├── Border.cs ├── Charts ├── Axis.cs ├── BarChart.cs ├── Chart.cs ├── LineChart.cs ├── PieChart.cs └── XElementHelpers.cs ├── Container.cs ├── Content.cs ├── ContentCollection.cs ├── CustomProperty.cs ├── DocProperty.cs ├── DocX.cs ├── DocXCore.csproj ├── DocumentTypes.cs ├── ExtensionsHeadings.cs ├── Font.cs ├── Footer.cs ├── Footers.cs ├── FormattedText.cs ├── Formatting.cs ├── Header.cs ├── Headers.cs ├── Help ├── DocX v1.0.0.10 - Documentation.chm └── Read Me.docx ├── HelperFunctions.cs ├── Hyperlink.cs ├── IContentContainer.cs ├── IParagraphContainer.cs ├── Image.cs ├── License └── License.html ├── List.cs ├── NETCorePort ├── Color.cs ├── DescriptionAttribute.cs └── StringExtensions.cs ├── PackagePartStream.cs ├── PageLayout.cs ├── Paragraph.cs ├── Picture.cs ├── Properties └── AssemblyInfo.cs ├── Resources ├── default_styles.xml.gz ├── numbering.default_bullet_abstract.xml.gz ├── numbering.default_decimal_abstract.xml.gz ├── numbering.xml.gz └── styles.xml.gz ├── Section.cs ├── Table.cs ├── TableOfContents.cs ├── _BaseClasses.cs ├── _Enumerations.cs └── _Extensions.cs /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | [Xx]64/ 19 | [Xx]86/ 20 | [Bb]uild/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | 85 | # Visual Studio profiler 86 | *.psess 87 | *.vsp 88 | *.vspx 89 | *.sap 90 | 91 | # TFS 2012 Local Workspace 92 | $tf/ 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | *.DotSettings.user 101 | 102 | # JustCode is a .NET coding add-in 103 | .JustCode 104 | 105 | # TeamCity is a build add-in 106 | _TeamCity* 107 | 108 | # DotCover is a Code Coverage Tool 109 | *.dotCover 110 | 111 | # NCrunch 112 | _NCrunch_* 113 | .*crunch*.local.xml 114 | nCrunchTemp_* 115 | 116 | # MightyMoose 117 | *.mm.* 118 | AutoTest.Net/ 119 | 120 | # Web workbench (sass) 121 | .sass-cache/ 122 | 123 | # Installshield output folder 124 | [Ee]xpress/ 125 | 126 | # DocProject is a documentation generator add-in 127 | DocProject/buildhelp/ 128 | DocProject/Help/*.HxT 129 | DocProject/Help/*.HxC 130 | DocProject/Help/*.hhc 131 | DocProject/Help/*.hhk 132 | DocProject/Help/*.hhp 133 | DocProject/Help/Html2 134 | DocProject/Help/html 135 | 136 | # Click-Once directory 137 | publish/ 138 | 139 | # Publish Web Output 140 | *.[Pp]ublish.xml 141 | *.azurePubxml 142 | 143 | # TODO: Un-comment the next line if you do not want to checkin 144 | # your web deploy settings because they may include unencrypted 145 | # passwords 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # NuGet Packages 150 | *.nupkg 151 | # The packages folder can be ignored because of Package Restore 152 | **/packages/* 153 | # except build/, which is used as an MSBuild target. 154 | !**/packages/build/ 155 | # Uncomment if necessary however generally it will be regenerated when needed 156 | #!**/packages/repositories.config 157 | # NuGet v3's project.json files produces more ignoreable files 158 | *.nuget.props 159 | *.nuget.targets 160 | 161 | # Microsoft Azure Build Output 162 | csx/ 163 | *.build.csdef 164 | 165 | # Microsoft Azure Emulator 166 | ecf/ 167 | rcf/ 168 | 169 | # Windows Store app package directory 170 | AppPackages/ 171 | BundleArtifacts/ 172 | 173 | # Visual Studio cache files 174 | # files ending in .cache can be ignored 175 | *.[Cc]ache 176 | # but keep track of directories ending in .cache 177 | !*.[Cc]ache/ 178 | 179 | # Others 180 | ClientBin/ 181 | [Ss]tyle[Cc]op.* 182 | ~$* 183 | *~ 184 | *.dbmdl 185 | *.dbproj.schemaview 186 | *.pfx 187 | *.publishsettings 188 | node_modules/ 189 | orleans.codegen.cs 190 | 191 | # RIA/Silverlight projects 192 | Generated_Code/ 193 | 194 | # Backup & report files from converting an old project file 195 | # to a newer Visual Studio version. Backup files are not needed, 196 | # because we have git ;-) 197 | _UpgradeReport_Files/ 198 | Backup*/ 199 | UpgradeLog*.XML 200 | UpgradeLog*.htm 201 | 202 | # SQL Server files 203 | *.mdf 204 | *.ldf 205 | 206 | # Business Intelligence projects 207 | *.rdl.data 208 | *.bim.layout 209 | *.bim_*.settings 210 | 211 | # Microsoft Fakes 212 | FakesAssemblies/ 213 | 214 | # GhostDoc plugin setting file 215 | *.GhostDoc.xml 216 | 217 | # Node.js Tools for Visual Studio 218 | .ntvs_analysis.dat 219 | 220 | # Visual Studio 6 build log 221 | *.plg 222 | 223 | # Visual Studio 6 workspace options file 224 | *.opt 225 | 226 | # Visual Studio LightSwitch build output 227 | **/*.HTMLClient/GeneratedArtifacts 228 | **/*.DesktopClient/GeneratedArtifacts 229 | **/*.DesktopClient/ModelManifest.xml 230 | **/*.Server/GeneratedArtifacts 231 | **/*.Server/ModelManifest.xml 232 | _Pvt_Extensions 233 | 234 | # LightSwitch generated files 235 | GeneratedArtifacts/ 236 | ModelManifest.xml 237 | 238 | # Paket dependency manager 239 | .paket/paket.exe 240 | 241 | # FAKE - F# Make 242 | .fake/ 243 | -------------------------------------------------------------------------------- /ConsoleApplication1/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /ConsoleApplication1/Console_NET471.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {E0357C33-1D97-44AB-9D44-60FFA638D2C7} 8 | Exe 9 | Properties 10 | ConsoleApplication1 11 | ConsoleApplication1 12 | v4.7.1 13 | 512 14 | true 15 | 16 | 17 | 18 | AnyCPU 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | ..\packages\DocX.1.1.0\lib\Xceed.Words.NET.dll 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | Always 64 | 65 | 66 | 67 | 74 | -------------------------------------------------------------------------------- /ConsoleApplication1/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Xceed.Words.NET; 7 | 8 | 9 | namespace ConsoleApplication1 10 | { 11 | class Program 12 | { 13 | static void Main(string[] args) 14 | { 15 | var doc = DocX.Create(@"MyFile.docx"); 16 | var p = doc.InsertParagraph(); 17 | p.Append("Hello World"); 18 | var i = doc.AddImage(@"purple.png"); 19 | var p2 = doc.InsertParagraph(); 20 | p2.AppendPicture(i.CreatePicture()); 21 | doc.Save(); 22 | 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ConsoleApplication1/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ConsoleApplication1")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Ich")] 12 | [assembly: AssemblyProduct("ConsoleApplication1")] 13 | [assembly: AssemblyCopyright("Copyright © Ich 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("e0357c33-1d97-44ab-9d44-60ffa638d2c7")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /ConsoleApplication1/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /ConsoleApplication1/purple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/ConsoleApplication1/purple.png -------------------------------------------------------------------------------- /DocX.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27428.2043 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{71370A98-6061-43F8-996D-E1D67B8E522E}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{FBEF23E6-99DF-4865-93AF-1F8DA991D32F}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DocXCore", "src\DocXCore\DocXCore.csproj", "{AA5D4778-4829-4EED-8957-19EE51E2DE5E}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Console_NET471", "ConsoleApplication1\Console_NET471.csproj", "{E0357C33-1D97-44AB-9D44-60FFA638D2C7}" 13 | EndProject 14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DocX.UnitTest", "src\DocX.UnitTest\DocX.UnitTest.csproj", "{4B113D33-3707-43A9-98F5-FAB24C80FDD8}" 15 | EndProject 16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DocX.ConsoleTest", "src\DocX.ConsoleTest\DocX.ConsoleTest.csproj", "{2C706118-6F25-4DD6-89C6-1CA80E98B23E}" 17 | EndProject 18 | Global 19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 20 | Debug|Any CPU = Debug|Any CPU 21 | Release|Any CPU = Release|Any CPU 22 | EndGlobalSection 23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 24 | {AA5D4778-4829-4EED-8957-19EE51E2DE5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {AA5D4778-4829-4EED-8957-19EE51E2DE5E}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {AA5D4778-4829-4EED-8957-19EE51E2DE5E}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {AA5D4778-4829-4EED-8957-19EE51E2DE5E}.Release|Any CPU.Build.0 = Release|Any CPU 28 | {E0357C33-1D97-44AB-9D44-60FFA638D2C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {E0357C33-1D97-44AB-9D44-60FFA638D2C7}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {E0357C33-1D97-44AB-9D44-60FFA638D2C7}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {E0357C33-1D97-44AB-9D44-60FFA638D2C7}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {4B113D33-3707-43A9-98F5-FAB24C80FDD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {4B113D33-3707-43A9-98F5-FAB24C80FDD8}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {4B113D33-3707-43A9-98F5-FAB24C80FDD8}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {4B113D33-3707-43A9-98F5-FAB24C80FDD8}.Release|Any CPU.Build.0 = Release|Any CPU 36 | {2C706118-6F25-4DD6-89C6-1CA80E98B23E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 37 | {2C706118-6F25-4DD6-89C6-1CA80E98B23E}.Debug|Any CPU.Build.0 = Debug|Any CPU 38 | {2C706118-6F25-4DD6-89C6-1CA80E98B23E}.Release|Any CPU.ActiveCfg = Release|Any CPU 39 | {2C706118-6F25-4DD6-89C6-1CA80E98B23E}.Release|Any CPU.Build.0 = Release|Any CPU 40 | EndGlobalSection 41 | GlobalSection(SolutionProperties) = preSolution 42 | HideSolutionNode = FALSE 43 | EndGlobalSection 44 | GlobalSection(NestedProjects) = preSolution 45 | {AA5D4778-4829-4EED-8957-19EE51E2DE5E} = {71370A98-6061-43F8-996D-E1D67B8E522E} 46 | {4B113D33-3707-43A9-98F5-FAB24C80FDD8} = {71370A98-6061-43F8-996D-E1D67B8E522E} 47 | {2C706118-6F25-4DD6-89C6-1CA80E98B23E} = {71370A98-6061-43F8-996D-E1D67B8E522E} 48 | EndGlobalSection 49 | GlobalSection(ExtensibilityGlobals) = postSolution 50 | SolutionGuid = {AC296EF9-DB5C-4A73-9E48-A5960452C679} 51 | EndGlobalSection 52 | EndGlobal 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | => https://github.com/WordDocX/DocX/issues/31 2 | 3 | Install-Package DocXCore -------------------------------------------------------------------------------- /pack.txt: -------------------------------------------------------------------------------- 1 | dotnet pack -c Release -o c:\temp\ -------------------------------------------------------------------------------- /src/DocX.ConsoleTest/DocX.ConsoleTest.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | Always 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/DocX.ConsoleTest/Program.cs: -------------------------------------------------------------------------------- 1 | // See https://aka.ms/new-console-template for more information 2 | 3 | 4 | using Novacode; 5 | 6 | var doc = DocX.Create(@"MyFile.docx"); 7 | var p = doc.InsertParagraph(); 8 | p.Append("Hello World"); 9 | var i = doc.AddImage("purple.png"); 10 | var p2 = doc.InsertParagraph(); 11 | p2.AppendPicture(i.CreatePicture()); 12 | 13 | doc.AddHeaders(); 14 | var pic = i.CreatePicture(); 15 | var hp = doc.Headers.odd.InsertParagraph(); 16 | hp.InsertPicture(pic); 17 | hp.InsertParagraphBeforeSelf(doc.InsertParagraph()); 18 | 19 | doc.Save(); -------------------------------------------------------------------------------- /src/DocX.ConsoleTest/purple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocX.ConsoleTest/purple.png -------------------------------------------------------------------------------- /src/DocX.UnitTest/AppendBookmark.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using Novacode; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | 8 | namespace UnitTests 9 | { 10 | [TestFixture] 11 | public class AppendBookmark 12 | { 13 | [Test] 14 | public void Bookmark_should_be_appended() 15 | { 16 | using (var doc = DocX.Create("")) 17 | { 18 | var paragraph = doc.InsertParagraph("A paragraph"); 19 | paragraph.AppendBookmark("bookmark"); 20 | var bookmarks = paragraph.GetBookmarks(); 21 | Assert.AreEqual(1, bookmarks.Count()); 22 | } 23 | } 24 | 25 | [Test] 26 | public void Bookmark_should_be_named_correctly() 27 | { 28 | using (var doc = DocX.Create("")) 29 | { 30 | var paragraph = doc.InsertParagraph("A paragraph"); 31 | paragraph.AppendBookmark("bookmark"); 32 | var bookmarks = paragraph.GetBookmarks(); 33 | Assert.AreEqual("bookmark", bookmarks.First().Name); 34 | } 35 | } 36 | 37 | [Test] 38 | public void Bookmark_should_reference_paragraph() 39 | { 40 | using (var doc = DocX.Create("")) 41 | { 42 | var paragraph = doc.InsertParagraph("A paragraph"); 43 | paragraph.AppendBookmark("bookmark"); 44 | var bookmarks = paragraph.GetBookmarks(); 45 | Assert.AreEqual(paragraph, bookmarks.First().Paragraph); 46 | } 47 | } 48 | 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/DocX.UnitTest/DocX.UnitTest.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | DocX.UnitTest 6 | DocX.UnitTest 7 | true 8 | false 9 | false 10 | false 11 | 12 | 13 | 14 | 15 | PreserveNewest 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/DocX.UnitTest/InsertAtBookmark.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Novacode; 3 | using System.Linq; 4 | using System.Collections.Generic; 5 | using NUnit.Framework; 6 | 7 | namespace UnitTests 8 | { 9 | [TestFixture] 10 | public class InsertAtBookmark 11 | { 12 | [Test] 13 | public void Inserting_at_bookmark_should_add_text_in_paragraph() 14 | { 15 | using (var document = DocX.Create("")) 16 | { 17 | document.InsertParagraph("Hello "); 18 | document.InsertBookmark("bookmark1"); 19 | document.InsertParagraph("!"); 20 | 21 | document.InsertAtBookmark("world", "bookmark1"); 22 | 23 | Assert.AreEqual("Hello world!", document.Text); 24 | 25 | } 26 | } 27 | 28 | [Test] 29 | public void Inserting_at_bookmark_should_add_text_in_header() 30 | { 31 | using (var document = DocX.Create("")) 32 | { 33 | document.AddHeaders(); 34 | var header = document.Headers.even; 35 | header.InsertParagraph("Hello "); 36 | header.InsertBookmark("bookmark1"); 37 | header.InsertParagraph("!"); 38 | 39 | document.InsertAtBookmark("world", "bookmark1"); 40 | 41 | Assert.AreEqual("Hello world!", String.Join("", header.Paragraphs.Select(x=>x.Text))); 42 | 43 | } 44 | } 45 | 46 | [Test] 47 | public void Inserting_at_bookmark_should_add_text_in_footer() 48 | { 49 | using (var document = DocX.Create("")) 50 | { 51 | document.AddHeaders(); 52 | var footer = document.Headers.even; 53 | footer.InsertParagraph("Hello "); 54 | footer.InsertBookmark("bookmark1"); 55 | footer.InsertParagraph("!"); 56 | 57 | document.InsertAtBookmark("world", "bookmark1"); 58 | 59 | Assert.AreEqual("Hello world!", String.Join("", footer.Paragraphs.Select(x => x.Text))); 60 | 61 | } 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/DocX.UnitTest/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("Ich")] 10 | [assembly: AssemblyProduct("DocX.UnitTest")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("4b113d33-3707-43a9-98f5-fab24c80fdd8")] 20 | -------------------------------------------------------------------------------- /src/DocX.UnitTest/RelativeDirectory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Reflection; 4 | 5 | namespace UnitTests 6 | { 7 | class RelativeDirectory 8 | { 9 | // Author D. Bolton see http://cplus.about.com (c) 2010 10 | private DirectoryInfo _dirInfo; 11 | 12 | public string Dir 13 | { 14 | get 15 | { 16 | return _dirInfo.Name; 17 | } 18 | } 19 | 20 | public string Path 21 | { 22 | get { return _dirInfo.FullName; } 23 | set 24 | { 25 | try 26 | { 27 | DirectoryInfo newDir = new DirectoryInfo(value); 28 | _dirInfo = newDir; 29 | } 30 | catch 31 | { 32 | // silent 33 | } 34 | } 35 | } 36 | public RelativeDirectory() 37 | { 38 | _dirInfo = new DirectoryInfo(Assembly.GetEntryAssembly().Location); 39 | } 40 | 41 | public RelativeDirectory(string absoluteDir) 42 | { 43 | _dirInfo = new DirectoryInfo(absoluteDir); 44 | } 45 | 46 | public Boolean Up(int numLevels) 47 | { 48 | for (int i = 0; i < numLevels; i++) 49 | { 50 | DirectoryInfo tempDir = _dirInfo.Parent; 51 | if (tempDir != null) 52 | _dirInfo = tempDir; 53 | else 54 | return false; 55 | } 56 | return true; 57 | } 58 | 59 | public Boolean Up() 60 | { 61 | return Up(1); 62 | } 63 | 64 | public Boolean Down(string match) 65 | { 66 | DirectoryInfo[] dirs = _dirInfo.GetDirectories(match + '*'); 67 | _dirInfo = dirs[0]; 68 | return true; 69 | } 70 | 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/DocX.UnitTest/ReplaceTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using System.Text.RegularExpressions; 4 | using NUnit.Framework; 5 | using Novacode; 6 | 7 | namespace UnitTests 8 | { 9 | [TestFixture] 10 | public class RegExTest 11 | { 12 | private readonly Dictionary _testPatterns = new Dictionary 13 | { 14 | { "COURT NAME", "Fred Frump" }, 15 | { "Case Number", "cr-md-2011-1234567" } 16 | }; 17 | 18 | [Test] 19 | public void ReplaceText_Can_ReplaceViaFunctionHandler() 20 | { 21 | using (var replaceDoc = DocX.Load(Path.Combine(TestHelper.DirectoryWithFiles, "ReplaceTests.docx"))) 22 | { 23 | foreach (var t in replaceDoc.Tables) 24 | { 25 | // each table has 1 row and 3 columns 26 | Assert.IsTrue(t.Rows[0].Cells.Count == 3); 27 | Assert.IsTrue(t.ColumnCount == 3); 28 | Assert.IsTrue(t.Rows.Count == 1); 29 | Assert.IsTrue(t.RowCount == 1); 30 | } 31 | 32 | // Make sure the origional strings are in the document. 33 | Assert.IsTrue(replaceDoc.FindAll("").Count == 2); 34 | Assert.IsTrue(replaceDoc.FindAll("").Count == 2); 35 | 36 | // There are only two patterns, even though each pattern is used more than once 37 | Assert.IsTrue(replaceDoc.FindUniqueByPattern(@"<[\w \=]{4,}>", RegexOptions.IgnoreCase).Count == 2); 38 | 39 | // Make sure the new strings are not in the document. 40 | Assert.IsTrue(replaceDoc.FindAll("Fred Frump").Count == 0); 41 | Assert.IsTrue(replaceDoc.FindAll("cr-md-2011-1234567").Count == 0); 42 | 43 | // Do the replacing 44 | replaceDoc.ReplaceText("<(.*?)>", ReplaceTextHandler, false, RegexOptions.IgnoreCase); 45 | 46 | // Make sure the origional string are no longer in the document. 47 | Assert.IsTrue(replaceDoc.FindAll("").Count == 0); 48 | Assert.IsTrue(replaceDoc.FindAll("").Count == 0); 49 | 50 | // Make sure the new strings are now in the document. 51 | Assert.IsTrue(replaceDoc.FindAll("FRED FRUMP").Count == 2); 52 | Assert.IsTrue(replaceDoc.FindAll("cr-md-2011-1234567").Count == 2); 53 | 54 | // Make sure the replacement worked. 55 | Assert.IsTrue(replaceDoc.Text 56 | == "\t\t\t\t\t\t\t\t\t\t\t\t\t\tThese two tables should look identical:\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tSTATE OF IOWA,\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tPlaintiff,\t\t\t\t\t\t\t\t\t\t\t\t\t\tvs.\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tFRED FRUMP,\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tDefendant.\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tCase No.: cr-md-2011-1234567\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tORDER SETTING ASIDE DEFAULT JUDGMENT\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tSTATE OF IOWA,\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tPlaintiff,\t\t\t\t\t\t\t\t\t\t\t\t\t\tvs.\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tFRED FRUMP,\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tDefendant.\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tCase No.: cr-md-2011-1234567\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tORDER SETTING ASIDE DEFAULT JUDGMENT\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"); 57 | } 58 | } 59 | 60 | private string ReplaceTextHandler(string findStr) 61 | { 62 | if (_testPatterns.ContainsKey(findStr)) 63 | { 64 | return _testPatterns[findStr]; 65 | } 66 | return findStr; 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /src/DocX.UnitTest/TestHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Reflection; 4 | 5 | namespace UnitTests 6 | { 7 | public static class TestHelper 8 | { 9 | static TestHelper() 10 | { 11 | string baseDirectory = System.AppContext.BaseDirectory; 12 | 13 | DirectoryWithFiles = Path.Combine(baseDirectory, "documents"); 14 | } 15 | 16 | public static string DirectoryWithFiles { get; } 17 | } 18 | } -------------------------------------------------------------------------------- /src/DocX.UnitTest/documents/..svnbridge/Template.dotx: -------------------------------------------------------------------------------- 1 | svn:mime-typeapplication/octet-stream -------------------------------------------------------------------------------- /src/DocX.UnitTest/documents/EverybodyHasAHome.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocX.UnitTest/documents/EverybodyHasAHome.docx -------------------------------------------------------------------------------- /src/DocX.UnitTest/documents/FontFormat.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocX.UnitTest/documents/FontFormat.docx -------------------------------------------------------------------------------- /src/DocX.UnitTest/documents/Hyperlinks.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocX.UnitTest/documents/Hyperlinks.docx -------------------------------------------------------------------------------- /src/DocX.UnitTest/documents/Images.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocX.UnitTest/documents/Images.docx -------------------------------------------------------------------------------- /src/DocX.UnitTest/documents/LargeTable.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocX.UnitTest/documents/LargeTable.docx -------------------------------------------------------------------------------- /src/DocX.UnitTest/documents/MovePicture.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocX.UnitTest/documents/MovePicture.docx -------------------------------------------------------------------------------- /src/DocX.UnitTest/documents/Paragraphs.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocX.UnitTest/documents/Paragraphs.docx -------------------------------------------------------------------------------- /src/DocX.UnitTest/documents/ReplaceTests.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocX.UnitTest/documents/ReplaceTests.docx -------------------------------------------------------------------------------- /src/DocX.UnitTest/documents/TableSpecifiedWidths.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocX.UnitTest/documents/TableSpecifiedWidths.docx -------------------------------------------------------------------------------- /src/DocX.UnitTest/documents/Tables.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocX.UnitTest/documents/Tables.docx -------------------------------------------------------------------------------- /src/DocX.UnitTest/documents/Template.dotx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocX.UnitTest/documents/Template.dotx -------------------------------------------------------------------------------- /src/DocX.UnitTest/documents/TestParent.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocX.UnitTest/documents/TestParent.docx -------------------------------------------------------------------------------- /src/DocX.UnitTest/documents/VariousTextFormatting - Kopie.docx.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocX.UnitTest/documents/VariousTextFormatting - Kopie.docx.zip -------------------------------------------------------------------------------- /src/DocX.UnitTest/documents/VariousTextFormatting.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocX.UnitTest/documents/VariousTextFormatting.docx -------------------------------------------------------------------------------- /src/DocX.UnitTest/documents/green.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocX.UnitTest/documents/green.jpg -------------------------------------------------------------------------------- /src/DocX.UnitTest/documents/orange.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocX.UnitTest/documents/orange.gif -------------------------------------------------------------------------------- /src/DocX.UnitTest/documents/purple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocX.UnitTest/documents/purple.png -------------------------------------------------------------------------------- /src/DocX.UnitTest/documents/red.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocX.UnitTest/documents/red.bmp -------------------------------------------------------------------------------- /src/DocX.UnitTest/documents/testdoc_OrderedList.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocX.UnitTest/documents/testdoc_OrderedList.docx -------------------------------------------------------------------------------- /src/DocX.UnitTest/documents/testdoc_OrderedUnorderedLists.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocX.UnitTest/documents/testdoc_OrderedUnorderedLists.docx -------------------------------------------------------------------------------- /src/DocX.UnitTest/documents/testdoc_SectionsWithHeadingBreaks.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocX.UnitTest/documents/testdoc_SectionsWithHeadingBreaks.docx -------------------------------------------------------------------------------- /src/DocX.UnitTest/documents/testdoc_SectionsWithSectionBreaks.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocX.UnitTest/documents/testdoc_SectionsWithSectionBreaks.docx -------------------------------------------------------------------------------- /src/DocX.UnitTest/documents/testdoc_SectionsWithSectionBreaksMultiParagraph.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocX.UnitTest/documents/testdoc_SectionsWithSectionBreaksMultiParagraph.docx -------------------------------------------------------------------------------- /src/DocX.UnitTest/documents/testdoc_UnorderedList.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocX.UnitTest/documents/testdoc_UnorderedList.docx -------------------------------------------------------------------------------- /src/DocX.UnitTest/documents/yellow.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocX.UnitTest/documents/yellow.tif -------------------------------------------------------------------------------- /src/DocXCore/Bookmark.cs: -------------------------------------------------------------------------------- 1 | namespace Novacode 2 | { 3 | public class Bookmark 4 | { 5 | public string Name { get; set; } 6 | public Paragraph Paragraph { get; set; } 7 | 8 | public void SetText(string newText) 9 | { 10 | Paragraph.ReplaceAtBookmark(newText, Name); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/DocXCore/BookmarkCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace Novacode 6 | { 7 | public class BookmarkCollection : List 8 | { 9 | public Bookmark this[string name] 10 | { 11 | get 12 | { 13 | return this.FirstOrDefault(bookmark => string.Equals(bookmark.Name, name, StringComparison.CurrentCultureIgnoreCase)); 14 | } 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/DocXCore/Border.cs: -------------------------------------------------------------------------------- 1 | using System.Drawing; 2 | 3 | namespace Novacode 4 | { 5 | /// 6 | /// Represents a border of a table or table cell 7 | /// Added by lckuiper @ 20101117 8 | /// 9 | public class Border 10 | { 11 | public BorderStyle Tcbs { get; set; } 12 | public BorderSize Size { get; set; } 13 | public int Space { get; set; } 14 | public Color Color { get; set; } 15 | public Border() 16 | { 17 | this.Tcbs = BorderStyle.Tcbs_single; 18 | this.Size = BorderSize.one; 19 | this.Space = 0; 20 | this.Color = Color.Black; 21 | } 22 | 23 | public Border(BorderStyle tcbs, BorderSize size, int space, Color color) 24 | { 25 | this.Tcbs = tcbs; 26 | this.Size = size; 27 | this.Space = space; 28 | this.Color = color; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/DocXCore/Charts/Axis.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Xml.Linq; 3 | 4 | namespace Novacode 5 | { 6 | /// 7 | /// Axis base class 8 | /// 9 | public abstract class Axis 10 | { 11 | /// 12 | /// ID of this Axis 13 | /// 14 | public String Id 15 | { 16 | get 17 | { 18 | return Xml.Element(XName.Get("axId", DocX.c.NamespaceName)).Attribute(XName.Get("val")).Value; 19 | } 20 | } 21 | 22 | /// 23 | /// Return true if this axis is visible 24 | /// 25 | public Boolean IsVisible 26 | { 27 | get 28 | { 29 | return Xml.Element(XName.Get("delete", DocX.c.NamespaceName)).Attribute(XName.Get("val")).Value == "0"; 30 | } 31 | set 32 | { 33 | if (value) 34 | Xml.Element(XName.Get("delete", DocX.c.NamespaceName)).Attribute(XName.Get("val")).Value = "0"; 35 | else 36 | Xml.Element(XName.Get("delete", DocX.c.NamespaceName)).Attribute(XName.Get("val")).Value = "1"; 37 | } 38 | } 39 | 40 | /// 41 | /// Axis xml element 42 | /// 43 | internal XElement Xml { get; set; } 44 | 45 | internal Axis(XElement xml) 46 | { 47 | Xml = xml; 48 | } 49 | 50 | public Axis(String id) 51 | { } 52 | } 53 | 54 | /// 55 | /// Represents Category Axes 56 | /// 57 | public class CategoryAxis : Axis 58 | { 59 | internal CategoryAxis(XElement xml) 60 | : base(xml) 61 | { } 62 | 63 | public CategoryAxis(String id) 64 | : base(id) 65 | { 66 | Xml = XElement.Parse(String.Format( 67 | @" 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | ", id)); 84 | } 85 | } 86 | 87 | /// 88 | /// Represents Values Axes 89 | /// 90 | public class ValueAxis : Axis 91 | { 92 | internal ValueAxis(XElement xml) 93 | : base(xml) 94 | { } 95 | 96 | public ValueAxis(String id) 97 | : base(id) 98 | { 99 | Xml = XElement.Parse(String.Format( 100 | @" 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | ", id)); 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/DocXCore/Charts/BarChart.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Xml.Linq; 3 | 4 | namespace Novacode 5 | { 6 | /// 7 | /// This element contains the 2-D bar or column series on this chart. 8 | /// 21.2.2.16 barChart (Bar Charts) 9 | /// 10 | public class BarChart : Chart 11 | { 12 | /// 13 | /// Specifies the possible directions for a bar chart. 14 | /// 15 | public BarDirection BarDirection 16 | { 17 | get 18 | { 19 | return XElementHelpers.GetValueToEnum( 20 | ChartXml.Element(XName.Get("barDir", DocX.c.NamespaceName))); 21 | } 22 | set 23 | { 24 | XElementHelpers.SetValueFromEnum( 25 | ChartXml.Element(XName.Get("barDir", DocX.c.NamespaceName)), value); 26 | } 27 | } 28 | 29 | /// 30 | /// Specifies the possible groupings for a bar chart. 31 | /// 32 | public BarGrouping BarGrouping 33 | { 34 | get 35 | { 36 | return XElementHelpers.GetValueToEnum( 37 | ChartXml.Element(XName.Get("grouping", DocX.c.NamespaceName))); 38 | } 39 | set 40 | { 41 | XElementHelpers.SetValueFromEnum( 42 | ChartXml.Element(XName.Get("grouping", DocX.c.NamespaceName)), value); 43 | } 44 | } 45 | 46 | /// 47 | /// Specifies that its contents contain a percentage between 0% and 500%. 48 | /// 49 | public Int32 GapWidth 50 | { 51 | get 52 | { 53 | return Convert.ToInt32( 54 | ChartXml.Element(XName.Get("gapWidth", DocX.c.NamespaceName)).Attribute(XName.Get("val")).Value); 55 | } 56 | set 57 | { 58 | if ((value < 1) || (value > 500)) 59 | throw new ArgumentException("GapWidth lay between 0% and 500%!"); 60 | ChartXml.Element(XName.Get("gapWidth", DocX.c.NamespaceName)).Attribute(XName.Get("val")).Value = value.ToString(); 61 | } 62 | } 63 | 64 | protected override XElement CreateChartXml() 65 | { 66 | return XElement.Parse( 67 | @" 68 | 69 | 70 | 71 | "); 72 | } 73 | } 74 | 75 | /// 76 | /// Specifies the possible directions for a bar chart. 77 | /// 21.2.3.3 ST_BarDir (Bar Direction) 78 | /// 79 | public enum BarDirection 80 | { 81 | [XmlName("col")] 82 | Column, 83 | [XmlName("bar")] 84 | Bar 85 | } 86 | 87 | /// 88 | /// Specifies the possible groupings for a bar chart. 89 | /// 21.2.3.4 ST_BarGrouping (Bar Grouping) 90 | /// 91 | public enum BarGrouping 92 | { 93 | [XmlName("clustered")] 94 | Clustered, 95 | [XmlName("percentStacked")] 96 | PercentStacked, 97 | [XmlName("stacked")] 98 | Stacked, 99 | [XmlName("standard")] 100 | Standard 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/DocXCore/Charts/Chart.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Xml.Linq; 5 | using System.Collections; 6 | using System.Drawing; 7 | using System.Reflection; 8 | 9 | namespace Novacode 10 | { 11 | /// 12 | /// Represents every Chart in this document. 13 | /// 14 | public abstract class Chart 15 | { 16 | protected XElement ChartXml { get; private set; } 17 | protected XElement ChartRootXml { get; private set; } 18 | 19 | /// 20 | /// The xml representation of this chart 21 | /// 22 | public XDocument Xml { get; private set; } 23 | 24 | #region Series 25 | 26 | /// 27 | /// Chart's series 28 | /// 29 | public List Series 30 | { 31 | get 32 | { 33 | List series = new List(); 34 | int indx = 1; 35 | foreach (XElement element in ChartXml.Elements(XName.Get("ser", DocX.c.NamespaceName))) 36 | { 37 | element.Add(new XElement(XName.Get("idx", DocX.c.NamespaceName)), (indx++).ToString()); 38 | series.Add(new Series(element)); 39 | } 40 | return series; 41 | } 42 | } 43 | 44 | /// 45 | /// Return maximum count of series 46 | /// 47 | public virtual Int16 MaxSeriesCount { get { return Int16.MaxValue; } } 48 | 49 | /// 50 | /// Add a new series to this chart 51 | /// 52 | public void AddSeries(Series series) 53 | { 54 | int serCount = ChartXml.Elements(XName.Get("ser", DocX.c.NamespaceName)).Count(); 55 | if (serCount == MaxSeriesCount) 56 | throw new InvalidOperationException("Maximum series for this chart is" + MaxSeriesCount.ToString() + "and have exceeded!"); 57 | // Sourceman 16.04.2015 - Every Series needs to have an order and index element for being processed by Word 2013 58 | series.Xml.AddFirst( 59 | new XElement(XName.Get("order", DocX.c.NamespaceName), 60 | new XAttribute(XName.Get("val"), (serCount + 1).ToString()))); 61 | series.Xml.AddFirst( 62 | new XElement(XName.Get("idx", DocX.c.NamespaceName), 63 | new XAttribute(XName.Get("val"), (serCount + 1).ToString()))); 64 | ChartXml.Add(series.Xml); 65 | } 66 | 67 | #endregion 68 | 69 | #region Legend 70 | 71 | /// 72 | /// Chart's legend. 73 | /// If legend doesn't exist property is null. 74 | /// 75 | public ChartLegend Legend { get; private set; } 76 | 77 | /// 78 | /// Add standart legend to the chart. 79 | /// 80 | public void AddLegend() 81 | { 82 | AddLegend(ChartLegendPosition.Right, false); 83 | } 84 | 85 | /// 86 | /// Add a legend with parameters to the chart. 87 | /// 88 | public void AddLegend(ChartLegendPosition position, Boolean overlay) 89 | { 90 | if (Legend != null) 91 | RemoveLegend(); 92 | Legend = new ChartLegend(position, overlay); 93 | //ChartRootXml.Add(Legend.Xml); 94 | // Sourceman: seems to be necessary to keep track of the order of elements as defined in the schema (Word 2013) 95 | ChartRootXml.Element(XName.Get("plotArea", DocX.c.NamespaceName)).AddAfterSelf(Legend.Xml); 96 | } 97 | 98 | /// 99 | /// Remove the legend from the chart. 100 | /// 101 | public void RemoveLegend() 102 | { 103 | Legend.Xml.Remove(); 104 | Legend = null; 105 | } 106 | 107 | #endregion 108 | 109 | #region Axis 110 | 111 | /// 112 | /// Represents the category axis 113 | /// 114 | public CategoryAxis CategoryAxis { get; private set; } 115 | 116 | /// 117 | /// Represents the values axis 118 | /// 119 | public ValueAxis ValueAxis { get; private set; } 120 | 121 | /// 122 | /// Represents existing the axis 123 | /// 124 | public virtual Boolean IsAxisExist { get { return true; } } 125 | 126 | #endregion 127 | 128 | /// 129 | /// Get or set 3D view for this chart 130 | /// 131 | public Boolean View3D 132 | { 133 | get 134 | { 135 | return ChartXml.Name.LocalName.Contains("3D"); 136 | } 137 | set 138 | { 139 | if (value) 140 | { 141 | if (!View3D) 142 | { 143 | String currentName = ChartXml.Name.LocalName; 144 | ChartXml.Name = XName.Get(currentName.Replace("Chart", "3DChart"), DocX.c.NamespaceName); 145 | } 146 | } 147 | else 148 | { 149 | if (View3D) 150 | { 151 | String currentName = ChartXml.Name.LocalName; 152 | ChartXml.Name = XName.Get(currentName.Replace("3DChart", "Chart"), DocX.c.NamespaceName); 153 | } 154 | } 155 | } 156 | } 157 | 158 | /// 159 | /// Specifies how blank cells shall be plotted on a chart 160 | /// 161 | public DisplayBlanksAs DisplayBlanksAs 162 | { 163 | get 164 | { 165 | return XElementHelpers.GetValueToEnum( 166 | ChartRootXml.Element(XName.Get("dispBlanksAs", DocX.c.NamespaceName))); 167 | } 168 | set 169 | { 170 | XElementHelpers.SetValueFromEnum( 171 | ChartRootXml.Element(XName.Get("dispBlanksAs", DocX.c.NamespaceName)), value); 172 | } 173 | } 174 | 175 | /// 176 | /// Create an Chart for this document 177 | /// 178 | public Chart() 179 | { 180 | // Create global xml 181 | Xml = XDocument.Parse 182 | (@" 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | "); 192 | 193 | // Create a real chart xml in an inheritor 194 | ChartXml = CreateChartXml(); 195 | 196 | // Create result plotarea element 197 | XElement plotAreaXml = new XElement( 198 | XName.Get("plotArea", DocX.c.NamespaceName), 199 | new XElement(XName.Get("layout", DocX.c.NamespaceName)), 200 | ChartXml); 201 | 202 | // Set labels 203 | XElement dLblsXml = XElement.Parse( 204 | @" 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | "); 213 | ChartXml.Add(dLblsXml); 214 | 215 | // if axes exists, create their 216 | if (IsAxisExist) 217 | { 218 | CategoryAxis = new CategoryAxis("148921728"); 219 | ValueAxis = new ValueAxis("154227840"); 220 | 221 | XElement axIDcatXml = XElement.Parse(String.Format( 222 | @"", CategoryAxis.Id)); 223 | XElement axIDvalXml = XElement.Parse(String.Format( 224 | @"", ValueAxis.Id)); 225 | 226 | // Sourceman: seems to be necessary to keep track of the order of elements as defined in the schema (Word 2013) 227 | var insertPoint = ChartXml.Element(XName.Get("gapWidth", DocX.c.NamespaceName)); 228 | if (insertPoint != null) { 229 | insertPoint.AddAfterSelf(axIDvalXml); 230 | insertPoint.AddAfterSelf(axIDcatXml); 231 | } else { 232 | ChartXml.Add(axIDcatXml); 233 | ChartXml.Add(axIDvalXml); 234 | } 235 | 236 | plotAreaXml.Add(CategoryAxis.Xml); 237 | plotAreaXml.Add(ValueAxis.Xml); 238 | } 239 | 240 | ChartRootXml = Xml.Root.Element(XName.Get("chart", DocX.c.NamespaceName)); 241 | //ChartRootXml.Add(plotAreaXml); 242 | ChartRootXml.Element(XName.Get("autoTitleDeleted", DocX.c.NamespaceName)).AddAfterSelf(plotAreaXml); 243 | } 244 | 245 | /// 246 | /// An abstract method which creates the current chart xml 247 | /// 248 | protected abstract XElement CreateChartXml(); 249 | } 250 | 251 | 252 | 253 | /// 254 | /// Represents a chart series 255 | /// 256 | public class Series 257 | { 258 | private XElement strCache; 259 | private XElement numCache; 260 | 261 | /// 262 | /// Series xml element 263 | /// 264 | internal XElement Xml { get; private set; } 265 | 266 | public Color Color 267 | { 268 | get 269 | { 270 | XElement colorElement = Xml.Element(XName.Get("spPr", DocX.c.NamespaceName)); 271 | if (colorElement == null) 272 | return Color.Transparent; 273 | else 274 | return Color.FromArgb(Int32.Parse( 275 | colorElement.Element(XName.Get("solidFill", DocX.a.NamespaceName)).Element(XName.Get("srgbClr", DocX.a.NamespaceName)).Attribute(XName.Get("val")).Value, 276 | System.Globalization.NumberStyles.HexNumber)); 277 | } 278 | set 279 | { 280 | XElement colorElement = Xml.Element(XName.Get("spPr", DocX.c.NamespaceName)); 281 | if (colorElement != null) 282 | colorElement.Remove(); 283 | colorElement = new XElement( 284 | XName.Get("spPr", DocX.c.NamespaceName), 285 | new XElement( 286 | XName.Get("solidFill", DocX.a.NamespaceName), 287 | new XElement( 288 | XName.Get("srgbClr", DocX.a.NamespaceName), 289 | new XAttribute(XName.Get("val"), value.ToHex())))); 290 | Xml.Element(XName.Get("tx", DocX.c.NamespaceName)).AddAfterSelf(colorElement); 291 | } 292 | } 293 | 294 | internal Series(XElement xml) 295 | { 296 | Xml = xml; 297 | strCache = xml.Element(XName.Get("cat", DocX.c.NamespaceName)).Element(XName.Get("strRef", DocX.c.NamespaceName)).Element(XName.Get("strCache", DocX.c.NamespaceName)); 298 | numCache = xml.Element(XName.Get("val", DocX.c.NamespaceName)).Element(XName.Get("numRef", DocX.c.NamespaceName)).Element(XName.Get("numCache", DocX.c.NamespaceName)); 299 | } 300 | 301 | public Series(String name) 302 | { 303 | strCache = new XElement(XName.Get("strCache", DocX.c.NamespaceName)); 304 | numCache = new XElement(XName.Get("numCache", DocX.c.NamespaceName)); 305 | 306 | Xml = new XElement( 307 | XName.Get("ser", DocX.c.NamespaceName), 308 | new XElement( 309 | XName.Get("tx", DocX.c.NamespaceName), 310 | new XElement( 311 | XName.Get("strRef", DocX.c.NamespaceName), 312 | new XElement(XName.Get("f", DocX.c.NamespaceName), ""), 313 | new XElement( 314 | XName.Get("strCache", DocX.c.NamespaceName), 315 | new XElement( 316 | XName.Get("pt", DocX.c.NamespaceName), 317 | new XAttribute(XName.Get("idx"), "0"), 318 | new XElement(XName.Get("v", DocX.c.NamespaceName), name) 319 | )))), 320 | new XElement(XName.Get("invertIfNegative", DocX.c.NamespaceName), "0"), 321 | new XElement( 322 | XName.Get("cat", DocX.c.NamespaceName), 323 | new XElement(XName.Get("strRef", DocX.c.NamespaceName), 324 | new XElement(XName.Get("f", DocX.c.NamespaceName), ""), 325 | strCache)), 326 | new XElement( 327 | XName.Get("val", DocX.c.NamespaceName), 328 | new XElement(XName.Get("numRef", DocX.c.NamespaceName), 329 | new XElement(XName.Get("f", DocX.c.NamespaceName), ""), 330 | numCache)) 331 | ); 332 | } 333 | 334 | public void Bind(ICollection list, String categoryPropertyName, String valuePropertyName) 335 | { 336 | XElement ptCount = new XElement(XName.Get("ptCount", DocX.c.NamespaceName), new XAttribute(XName.Get("val"), list.Count)); 337 | XElement formatCode = new XElement(XName.Get("formatCode", DocX.c.NamespaceName), "General"); 338 | 339 | strCache.RemoveAll(); 340 | numCache.RemoveAll(); 341 | 342 | strCache.Add(ptCount); 343 | numCache.Add(formatCode); 344 | numCache.Add(ptCount); 345 | 346 | Int32 index = 0; 347 | XElement pt; 348 | foreach (var item in list) 349 | { 350 | pt = new XElement(XName.Get("pt", DocX.c.NamespaceName), new XAttribute(XName.Get("idx"), index), 351 | new XElement(XName.Get("v", DocX.c.NamespaceName), item.GetType().GetProperty(categoryPropertyName).GetValue(item, null))); 352 | strCache.Add(pt); 353 | pt = new XElement(XName.Get("pt", DocX.c.NamespaceName), new XAttribute(XName.Get("idx"), index), 354 | new XElement(XName.Get("v", DocX.c.NamespaceName), item.GetType().GetProperty(valuePropertyName).GetValue(item, null))); 355 | numCache.Add(pt); 356 | index++; 357 | } 358 | } 359 | 360 | public void Bind(IList categories, IList values) 361 | { 362 | if (categories.Count != values.Count) 363 | throw new ArgumentException("Categories count must equal to Values count"); 364 | 365 | XElement ptCount = new XElement(XName.Get("ptCount", DocX.c.NamespaceName), new XAttribute(XName.Get("val"), categories.Count)); 366 | XElement formatCode = new XElement(XName.Get("formatCode", DocX.c.NamespaceName), "General"); 367 | 368 | strCache.RemoveAll(); 369 | numCache.RemoveAll(); 370 | 371 | strCache.Add(ptCount); 372 | numCache.Add(formatCode); 373 | numCache.Add(ptCount); 374 | 375 | XElement pt; 376 | for (int index = 0; index < categories.Count; index++) 377 | { 378 | pt = new XElement(XName.Get("pt", DocX.c.NamespaceName), new XAttribute(XName.Get("idx"), index), 379 | new XElement(XName.Get("v", DocX.c.NamespaceName), categories[index].ToString())); 380 | strCache.Add(pt); 381 | pt = new XElement(XName.Get("pt", DocX.c.NamespaceName), new XAttribute(XName.Get("idx"), index), 382 | new XElement(XName.Get("v", DocX.c.NamespaceName), values[index].ToString())); 383 | numCache.Add(pt); 384 | } 385 | } 386 | } 387 | 388 | /// 389 | /// Represents a chart legend 390 | /// More: http://msdn.microsoft.com/ru-ru/library/cc845123.aspx 391 | /// 392 | public class ChartLegend 393 | { 394 | /// 395 | /// Legend xml element 396 | /// 397 | internal XElement Xml { get; private set; } 398 | 399 | /// 400 | /// Specifies that other chart elements shall be allowed to overlap this chart element 401 | /// 402 | public Boolean Overlay 403 | { 404 | get { return Xml.Element(XName.Get("overlay", DocX.c.NamespaceName)).Attribute("val").Value == "1"; } 405 | set { Xml.Element(XName.Get("overlay", DocX.c.NamespaceName)).Attribute("val").Value = GetOverlayValue(value); } 406 | } 407 | 408 | /// 409 | /// Specifies the possible positions for a legend 410 | /// 411 | public ChartLegendPosition Position 412 | { 413 | get 414 | { 415 | return XElementHelpers.GetValueToEnum( 416 | Xml.Element(XName.Get("legendPos", DocX.c.NamespaceName))); 417 | } 418 | set 419 | { 420 | XElementHelpers.SetValueFromEnum( 421 | Xml.Element(XName.Get("legendPos", DocX.c.NamespaceName)), value); 422 | } 423 | } 424 | 425 | internal ChartLegend(ChartLegendPosition position, Boolean overlay) 426 | { 427 | Xml = new XElement( 428 | XName.Get("legend", DocX.c.NamespaceName), 429 | new XElement(XName.Get("legendPos", DocX.c.NamespaceName), new XAttribute("val", XElementHelpers.GetXmlNameFromEnum(position))), 430 | new XElement(XName.Get("overlay", DocX.c.NamespaceName), new XAttribute("val", GetOverlayValue(overlay))) 431 | ); 432 | } 433 | 434 | /// 435 | /// ECMA-376, page 3840 436 | /// 21.2.2.132 overlay (Overlay) 437 | /// 438 | private String GetOverlayValue(Boolean overlay) 439 | { 440 | if (overlay) 441 | return "1"; 442 | else 443 | return "0"; 444 | } 445 | } 446 | 447 | /// 448 | /// Specifies the possible positions for a legend. 449 | /// 21.2.3.24 ST_LegendPos (Legend Position) 450 | /// 451 | public enum ChartLegendPosition 452 | { 453 | [XmlName("t")] 454 | Top, 455 | [XmlName("b")] 456 | Bottom, 457 | [XmlName("l")] 458 | Left, 459 | [XmlName("r")] 460 | Right, 461 | [XmlName("tr")] 462 | TopRight 463 | } 464 | 465 | /// 466 | /// Specifies the possible ways to display blanks. 467 | /// 21.2.3.10 ST_DispBlanksAs (Display Blanks As) 468 | /// 469 | public enum DisplayBlanksAs 470 | { 471 | [XmlName("gap")] 472 | Gap, 473 | [XmlName("span")] 474 | Span, 475 | [XmlName("zero")] 476 | Zero 477 | } 478 | } 479 | -------------------------------------------------------------------------------- /src/DocXCore/Charts/LineChart.cs: -------------------------------------------------------------------------------- 1 | using System.Xml.Linq; 2 | 3 | namespace Novacode 4 | { 5 | /// 6 | /// This element contains the 2-D line chart series. 7 | /// 21.2.2.97 lineChart (Line Charts) 8 | /// 9 | public class LineChart: Chart 10 | { 11 | /// 12 | /// Specifies the kind of grouping for a column, line, or area chart. 13 | /// 14 | public Grouping Grouping 15 | { 16 | get 17 | { 18 | return XElementHelpers.GetValueToEnum( 19 | ChartXml.Element(XName.Get("grouping", DocX.c.NamespaceName))); 20 | } 21 | set 22 | { 23 | XElementHelpers.SetValueFromEnum( 24 | ChartXml.Element(XName.Get("grouping", DocX.c.NamespaceName)), value); 25 | } 26 | } 27 | 28 | protected override XElement CreateChartXml() 29 | { 30 | return XElement.Parse( 31 | @" 32 | 33 | "); 34 | } 35 | } 36 | 37 | /// 38 | /// Specifies the kind of grouping for a column, line, or area chart. 39 | /// 21.2.2.76 grouping (Grouping) 40 | /// 41 | public enum Grouping 42 | { 43 | [XmlName("percentStacked")] 44 | PercentStacked, 45 | [XmlName("stacked")] 46 | Stacked, 47 | [XmlName("standard")] 48 | Standard 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/DocXCore/Charts/PieChart.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Xml.Linq; 3 | 4 | namespace Novacode 5 | { 6 | /// 7 | /// This element contains the 2-D pie series for this chart. 8 | /// 21.2.2.141 pieChart (Pie Charts) 9 | /// 10 | public class PieChart : Chart 11 | { 12 | public override Boolean IsAxisExist { get { return false; } } 13 | public override Int16 MaxSeriesCount { get { return 1; } } 14 | 15 | protected override XElement CreateChartXml() 16 | { 17 | return XElement.Parse( 18 | @" 19 | "); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/DocXCore/Charts/XElementHelpers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Reflection; 4 | using System.Xml.Linq; 5 | 6 | namespace Novacode 7 | { 8 | internal static class XElementHelpers 9 | { 10 | /// 11 | /// Get value from XElement and convert it to enum 12 | /// 13 | /// Enum type 14 | internal static T GetValueToEnum(XElement element) 15 | { 16 | if (element == null) 17 | throw new ArgumentNullException(nameof(element)); 18 | 19 | String value = element.Attribute(XName.Get("val")).Value; 20 | foreach (T e in Enum.GetValues(typeof(T))) 21 | { 22 | FieldInfo fi = typeof(T).GetField(e.ToString()); 23 | if (fi.GetCustomAttributes(typeof(XmlNameAttribute), false).Count() == 0) 24 | throw new Exception(String.Format("Attribute 'XmlNameAttribute' is not assigned to {0} fields!", typeof(T).Name)); 25 | XmlNameAttribute a = (XmlNameAttribute)fi.GetCustomAttributes(typeof(XmlNameAttribute), false).First(); 26 | if (a.XmlName == value) 27 | return e; 28 | } 29 | throw new ArgumentException("Invalid element value!"); 30 | } 31 | 32 | /// 33 | /// Convert value to xml string and set it into XElement 34 | /// 35 | /// Enum type 36 | internal static void SetValueFromEnum(XElement element, T value) 37 | { 38 | if (element == null) 39 | throw new ArgumentNullException(nameof(element)); 40 | element.Attribute(XName.Get("val")).Value = GetXmlNameFromEnum(value); 41 | } 42 | 43 | /// 44 | /// Return xml string for this value 45 | /// 46 | /// Enum type 47 | internal static String GetXmlNameFromEnum(T value) 48 | { 49 | if (value == null) 50 | throw new ArgumentNullException(nameof(value)); 51 | 52 | FieldInfo fi = typeof(T).GetField(value.ToString()); 53 | if (fi.GetCustomAttributes(typeof(XmlNameAttribute), false).Count() == 0) 54 | throw new Exception(String.Format("Attribute 'XmlNameAttribute' is not assigned to {0} fields!", typeof(T).Name)); 55 | XmlNameAttribute a = (XmlNameAttribute)fi.GetCustomAttributes(typeof(XmlNameAttribute), false).First(); 56 | return a.XmlName; 57 | } 58 | } 59 | 60 | /// 61 | /// This attribute applied to enum's fields for definition their's real xml names in DocX file. 62 | /// 63 | /// 64 | /// public enum MyEnum 65 | /// { 66 | /// [XmlName("one")] // This means, that xml element has 'val="one"' 67 | /// ValueOne, 68 | /// [XmlName("two")] // This means, that xml element has 'val="two"' 69 | /// ValueTwo 70 | /// } 71 | /// 72 | [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)] 73 | internal sealed class XmlNameAttribute : Attribute 74 | { 75 | /// 76 | /// Real xml name 77 | /// 78 | public String XmlName { get; private set; } 79 | 80 | public XmlNameAttribute(String xmlName) 81 | { 82 | XmlName = xmlName; 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/DocXCore/Content.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Collections.Generic; 3 | using System.Xml.Linq; 4 | 5 | namespace Novacode 6 | { 7 | public class Content : InsertBeforeOrAfter 8 | { 9 | 10 | public string Name { get; set; } 11 | public string Tag { get; set; } 12 | public string Text { get; set; } 13 | public List Sections { get; set; } 14 | public ContainerType ParentContainer; 15 | 16 | 17 | internal Content(DocX document, XElement xml, int startIndex) 18 | : base(document, xml) 19 | { 20 | 21 | } 22 | 23 | public void SetText(string newText) 24 | { 25 | Xml.Descendants(XName.Get("t", DocX.w.NamespaceName)).First().Value = newText; 26 | } 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/DocXCore/ContentCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace Novacode 6 | { 7 | public class ContentCollection : List 8 | { 9 | public Content this[string name] 10 | { 11 | get 12 | { 13 | return this.FirstOrDefault(content => string.Equals(content.Name, name, StringComparison.CurrentCultureIgnoreCase)); 14 | } 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/DocXCore/CustomProperty.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Novacode 4 | { 5 | public class CustomProperty 6 | { 7 | /// 8 | /// The name of this CustomProperty. 9 | /// 10 | public string Name { get; } 11 | 12 | /// 13 | /// The value of this CustomProperty. 14 | /// 15 | public object Value { get; } 16 | 17 | internal string Type { get; } 18 | 19 | internal CustomProperty(string name, string type, string value) 20 | { 21 | object realValue; 22 | switch (type) 23 | { 24 | case "lpwstr": 25 | { 26 | realValue = value; 27 | break; 28 | } 29 | 30 | case "i4": 31 | { 32 | realValue = int.Parse(value, System.Globalization.CultureInfo.InvariantCulture); 33 | break; 34 | } 35 | 36 | case "r8": 37 | { 38 | realValue = Double.Parse(value, System.Globalization.CultureInfo.InvariantCulture); 39 | break; 40 | } 41 | 42 | case "filetime": 43 | { 44 | realValue = DateTime.Parse(value, System.Globalization.CultureInfo.InvariantCulture); 45 | break; 46 | } 47 | 48 | case "bool": 49 | { 50 | realValue = bool.Parse(value); 51 | break; 52 | } 53 | 54 | default: throw new Exception(); 55 | } 56 | 57 | Name = name; 58 | Type = type; 59 | Value = realValue; 60 | } 61 | 62 | private CustomProperty(string name, string type, object value) 63 | { 64 | Name = name; 65 | Type = type; 66 | Value = value; 67 | } 68 | 69 | /// 70 | /// Create a new CustomProperty to hold a string. 71 | /// 72 | /// The name of this CustomProperty. 73 | /// The value of this CustomProperty. 74 | public CustomProperty(string name, string value) : this(name, "lpwstr", value as object) { } 75 | 76 | 77 | /// 78 | /// Create a new CustomProperty to hold an int. 79 | /// 80 | /// The name of this CustomProperty. 81 | /// The value of this CustomProperty. 82 | public CustomProperty(string name, int value) : this(name, "i4", value) { } 83 | 84 | 85 | /// 86 | /// Create a new CustomProperty to hold a double. 87 | /// 88 | /// The name of this CustomProperty. 89 | /// The value of this CustomProperty. 90 | public CustomProperty(string name, double value) : this(name, "r8", value) { } 91 | 92 | 93 | /// 94 | /// Create a new CustomProperty to hold a DateTime. 95 | /// 96 | /// The name of this CustomProperty. 97 | /// The value of this CustomProperty. 98 | public CustomProperty(string name, DateTime value) : this(name, "filetime", value.ToUniversalTime()) { } 99 | 100 | /// 101 | /// Create a new CustomProperty to hold a bool. 102 | /// 103 | /// The name of this CustomProperty. 104 | /// The value of this CustomProperty. 105 | public CustomProperty(string name, bool value) : this(name, "bool", value) { } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/DocXCore/DocProperty.cs: -------------------------------------------------------------------------------- 1 | using System.Xml.Linq; 2 | using System.Text.RegularExpressions; 3 | 4 | namespace Novacode 5 | { 6 | /// 7 | /// Represents a field of type document property. This field displays the value stored in a custom property. 8 | /// 9 | public class DocProperty: DocXElement 10 | { 11 | internal Regex extractName = new Regex(@"DOCPROPERTY (?.*) "); 12 | 13 | /// 14 | /// The custom property to display. 15 | /// 16 | public string Name { get; } 17 | 18 | internal DocProperty(DocX document, XElement xml):base(document, xml) 19 | { 20 | string instr = Xml.Attribute(XName.Get("instr", "http://schemas.openxmlformats.org/wordprocessingml/2006/main")).Value; 21 | Name = extractName.Match(instr.Trim()).Groups["name"].Value; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/DocXCore/DocXCore.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | DocX is a .NET library that allows developers to manipulate Word 2007 files, in an easy and intuitive manor. This is a fork of DocX for .NET Core. 5 | 1.0.2 6 | Catahl Coffey 7 | net471;netstandard2.0 8 | DocXCore 9 | DocXCore 10 | Word;DocX 11 | Updated for .NET Core to 2.0 12 | http://download.codeplex.com/Project/Download/FileDownload.aspx?ProjectName=docx&amp;DownloadId=83756&amp;Build=17950 13 | https://github.com/Jetro223/DocXNETCore 14 | http://docx.codeplex.com/license 15 | 2.0.0 16 | false 17 | false 18 | false 19 | false 20 | false 21 | false 22 | false 23 | false 24 | 25 | Library 26 | 27 | 1.0.10 28 | 29 | 30 | 31 | TRACE;DEBUG;NET471; 32 | 33 | 34 | 35 | TRACE;RELEASE;NET471; 36 | 37 | 38 | 39 | TRACE;DEBUG;NET_STANDARD; 40 | 41 | 42 | 43 | TRACE;RELEASE;NET_STANDARD; 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | all 65 | runtime; build; native; contentfiles; analyzers; buildtransitive 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /src/DocXCore/DocumentTypes.cs: -------------------------------------------------------------------------------- 1 | namespace Novacode 2 | { 3 | public enum DocumentTypes 4 | { 5 | Document, 6 | Template 7 | } 8 | } -------------------------------------------------------------------------------- /src/DocXCore/ExtensionsHeadings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Reflection; 4 | 5 | namespace Novacode 6 | { 7 | public static class ExtensionsHeadings 8 | { 9 | public static Paragraph Heading(this Paragraph paragraph, HeadingType headingType) 10 | { 11 | string StyleName = headingType.EnumDescription(); 12 | paragraph.StyleName = StyleName; 13 | return paragraph; 14 | } 15 | 16 | public static string EnumDescription(this Enum enumValue) 17 | { 18 | if (enumValue == null || enumValue.ToString() == "0") 19 | { 20 | return string.Empty; 21 | } 22 | FieldInfo enumInfo = enumValue.GetType().GetField(enumValue.ToString()); 23 | DescriptionAttribute[] enumAttributes = (DescriptionAttribute[])enumInfo.GetCustomAttributes(typeof(DescriptionAttribute), false); 24 | if (enumAttributes.Length > 0) 25 | { 26 | return enumAttributes[0].Description; 27 | } 28 | return enumValue.ToString(); 29 | } 30 | 31 | /// 32 | /// From: http://stackoverflow.com/questions/4108828/generic-extension-method-to-see-if-an-enum-contains-a-flag 33 | /// Check to see if a flags enumeration has a specific flag set. 34 | /// 35 | /// Flags enumeration to check 36 | /// Flag to check for 37 | /// 38 | public static bool HasFlag(this Enum variable, Enum value) 39 | { 40 | if (variable == null) 41 | return false; 42 | 43 | if (value == null) 44 | throw new ArgumentNullException(nameof(value)); 45 | 46 | // Not as good as the .NET 4 version of this function, but should be good enough 47 | if (!Enum.IsDefined(variable.GetType(), value)) 48 | { 49 | throw new ArgumentException(string.Format( 50 | "Enumeration type mismatch. The flag is of type '{0}', was expecting '{1}'.", 51 | value.GetType(), variable.GetType())); 52 | } 53 | 54 | ulong num = Convert.ToUInt64(value); 55 | return ((Convert.ToUInt64(variable) & num) == num); 56 | 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/DocXCore/Font.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Novacode 4 | { 5 | /// 6 | /// Represents a font family 7 | /// 8 | public sealed class Font 9 | { 10 | /// 11 | /// Initializes a new instance of 12 | /// 13 | /// The name of the font family 14 | public Font(string name) 15 | { 16 | if (string.IsNullOrEmpty(name)) 17 | { 18 | throw new ArgumentNullException(nameof(name)); 19 | } 20 | 21 | Name = name; 22 | } 23 | 24 | /// 25 | /// The name of the font family 26 | /// 27 | public string Name { get; private set; } 28 | 29 | /// 30 | /// Returns a string representation of an object 31 | /// 32 | /// The name of the font family 33 | public override string ToString() 34 | { 35 | return Name; 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/DocXCore/Footer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Xml.Linq; 4 | using System.IO.Packaging; 5 | using System.Collections.ObjectModel; 6 | 7 | namespace Novacode 8 | { 9 | public class Footer : Container, IParagraphContainer 10 | { 11 | public bool PageNumbers 12 | { 13 | get 14 | { 15 | return false; 16 | } 17 | 18 | set 19 | { 20 | XElement e = XElement.Parse 21 | (@" 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 1 41 | 42 | 43 | 44 | 45 | " 46 | ); 47 | 48 | Xml.AddFirst(e); 49 | } 50 | } 51 | 52 | internal Footer(DocX document, XElement xml, PackagePart mainPart): base(document, xml) 53 | { 54 | this.mainPart = mainPart; 55 | } 56 | 57 | public override Paragraph InsertParagraph() 58 | { 59 | Paragraph p = base.InsertParagraph(); 60 | p.PackagePart = mainPart; 61 | return p; 62 | } 63 | 64 | public override Paragraph InsertParagraph(int index, string text, bool trackChanges) 65 | { 66 | Paragraph p = base.InsertParagraph(index, text, trackChanges); 67 | p.PackagePart = mainPart; 68 | return p; 69 | } 70 | 71 | public override Paragraph InsertParagraph(Paragraph p) 72 | { 73 | p.PackagePart = mainPart; 74 | return base.InsertParagraph(p); 75 | } 76 | 77 | public override Paragraph InsertParagraph(int index, Paragraph p) 78 | { 79 | p.PackagePart = mainPart; 80 | return base.InsertParagraph(index, p); 81 | } 82 | 83 | public override Paragraph InsertParagraph(int index, string text, bool trackChanges, Formatting formatting) 84 | { 85 | Paragraph p = base.InsertParagraph(index, text, trackChanges, formatting); 86 | p.PackagePart = mainPart; 87 | return p; 88 | } 89 | 90 | public override Paragraph InsertParagraph(string text) 91 | { 92 | Paragraph p = base.InsertParagraph(text); 93 | p.PackagePart = mainPart; 94 | return p; 95 | } 96 | 97 | public override Paragraph InsertParagraph(string text, bool trackChanges) 98 | { 99 | Paragraph p = base.InsertParagraph(text, trackChanges); 100 | p.PackagePart = mainPart; 101 | return p; 102 | } 103 | 104 | public override Paragraph InsertParagraph(string text, bool trackChanges, Formatting formatting) 105 | { 106 | Paragraph p = base.InsertParagraph(text, trackChanges, formatting); 107 | p.PackagePart = mainPart; 108 | 109 | return p; 110 | } 111 | 112 | public override Paragraph InsertEquation(String equation) 113 | { 114 | Paragraph p = base.InsertEquation(equation); 115 | p.PackagePart = mainPart; 116 | return p; 117 | } 118 | 119 | public override ReadOnlyCollection Paragraphs 120 | { 121 | get 122 | { 123 | ReadOnlyCollection l = base.Paragraphs; 124 | foreach (var paragraph in l) 125 | { 126 | paragraph.mainPart = mainPart; 127 | } 128 | return l; 129 | } 130 | } 131 | 132 | public override List Tables 133 | { 134 | get 135 | { 136 | List
l = base.Tables; 137 | l.ForEach(x => x.mainPart = mainPart); 138 | return l; 139 | } 140 | } 141 | public new Table InsertTable(int rowCount, int columnCount) 142 | { 143 | if (rowCount < 1 || columnCount < 1) 144 | throw new ArgumentOutOfRangeException("Row and Column count must be greater than zero."); 145 | 146 | Table t = base.InsertTable(rowCount, columnCount); 147 | t.mainPart = mainPart; 148 | return t; 149 | } 150 | public new Table InsertTable(int index, Table t) 151 | { 152 | Table t2 = base.InsertTable(index, t); 153 | t2.mainPart = mainPart; 154 | return t2; 155 | } 156 | public new Table InsertTable(Table t) 157 | { 158 | t = base.InsertTable(t); 159 | t.mainPart = mainPart; 160 | return t; 161 | } 162 | public new Table InsertTable(int index, int rowCount, int columnCount) 163 | { 164 | if (rowCount < 1 || columnCount < 1) 165 | throw new ArgumentOutOfRangeException("Row and Column count must be greater than zero."); 166 | 167 | Table t = base.InsertTable(index, rowCount, columnCount); 168 | t.mainPart = mainPart; 169 | return t; 170 | } 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /src/DocXCore/Footers.cs: -------------------------------------------------------------------------------- 1 | namespace Novacode 2 | { 3 | public class Footers 4 | { 5 | internal Footers() 6 | { 7 | 8 | } 9 | 10 | public Footer odd; 11 | public Footer even; 12 | public Footer first; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/DocXCore/FormattedText.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Novacode 4 | { 5 | public class FormattedText: IComparable 6 | { 7 | public FormattedText() 8 | { 9 | 10 | } 11 | 12 | public int index; 13 | public string text; 14 | public Formatting formatting; 15 | 16 | public int CompareTo(object obj) 17 | { 18 | FormattedText other = (FormattedText)obj; 19 | FormattedText tf = this; 20 | 21 | if (other.formatting == null || tf.formatting == null) 22 | return -1; 23 | 24 | return tf.formatting.CompareTo(other.formatting); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/DocXCore/Formatting.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Xml.Linq; 4 | using System.Drawing; 5 | using System.Globalization; 6 | namespace Novacode 7 | { 8 | /// 9 | /// A text formatting. 10 | /// 11 | public class Formatting : IComparable 12 | { 13 | private XElement rPr; 14 | private bool? hidden; 15 | private bool? bold; 16 | private bool? italic; 17 | private StrikeThrough? strikethrough; 18 | private Script? script; 19 | private Highlight? highlight; 20 | private double? size; 21 | private Color? fontColor; 22 | private Color? underlineColor; 23 | private UnderlineStyle? underlineStyle; 24 | private Misc? misc; 25 | private CapsStyle? capsStyle; 26 | private Font fontFamily; 27 | private int? percentageScale; 28 | private int? kerning; 29 | private int? position; 30 | private double? spacing; 31 | 32 | private CultureInfo language; 33 | 34 | /// 35 | /// A text formatting. 36 | /// 37 | public Formatting() 38 | { 39 | capsStyle = Novacode.CapsStyle.none; 40 | strikethrough = Novacode.StrikeThrough.none; 41 | script = Novacode.Script.none; 42 | highlight = Novacode.Highlight.none; 43 | underlineStyle = Novacode.UnderlineStyle.none; 44 | misc = Novacode.Misc.none; 45 | 46 | // Use current culture by default 47 | language = CultureInfo.CurrentCulture; 48 | 49 | rPr = new XElement(XName.Get("rPr", DocX.w.NamespaceName)); 50 | } 51 | 52 | /// 53 | /// Text language 54 | /// 55 | public CultureInfo Language 56 | { 57 | get 58 | { 59 | return language; 60 | } 61 | 62 | set 63 | { 64 | language = value; 65 | } 66 | } 67 | 68 | /// 69 | /// Returns a new identical instance of Formatting. 70 | /// 71 | /// 72 | public Formatting Clone() 73 | { 74 | Formatting newf = new Formatting(); 75 | newf.Bold = bold; 76 | newf.CapsStyle = capsStyle; 77 | newf.FontColor = fontColor; 78 | newf.FontFamily = fontFamily; 79 | newf.Hidden = hidden; 80 | newf.Highlight = highlight; 81 | newf.Italic = italic; 82 | if (kerning.HasValue) { newf.Kerning = kerning; } 83 | newf.Language = language; 84 | newf.Misc = misc; 85 | if (percentageScale.HasValue) { newf.PercentageScale = percentageScale; } 86 | if (position.HasValue) { newf.Position = position; } 87 | newf.Script = script; 88 | if (size.HasValue) { newf.Size = size; } 89 | if (spacing.HasValue) { newf.Spacing = spacing; } 90 | newf.StrikeThrough = strikethrough; 91 | newf.UnderlineColor = underlineColor; 92 | newf.UnderlineStyle = underlineStyle; 93 | return newf; 94 | } 95 | 96 | public static Formatting Parse(XElement rPr) 97 | { 98 | Formatting formatting = new Formatting(); 99 | 100 | // Build up the Formatting object. 101 | foreach (XElement option in rPr.Elements()) 102 | { 103 | switch (option.Name.LocalName) 104 | { 105 | case "lang": 106 | formatting.Language = new CultureInfo( 107 | option.GetAttribute(XName.Get("val", DocX.w.NamespaceName), null) ?? 108 | option.GetAttribute(XName.Get("eastAsia", DocX.w.NamespaceName), null) ?? 109 | option.GetAttribute(XName.Get("bidi", DocX.w.NamespaceName))); 110 | break; 111 | case "spacing": 112 | formatting.Spacing = Double.Parse( 113 | option.GetAttribute(XName.Get("val", DocX.w.NamespaceName))) / 20.0; 114 | break; 115 | case "position": 116 | formatting.Position = Int32.Parse( 117 | option.GetAttribute(XName.Get("val", DocX.w.NamespaceName))) / 2; 118 | break; 119 | case "kern": 120 | formatting.Position = Int32.Parse( 121 | option.GetAttribute(XName.Get("val", DocX.w.NamespaceName))) / 2; 122 | break; 123 | case "w": 124 | formatting.PercentageScale = Int32.Parse( 125 | option.GetAttribute(XName.Get("val", DocX.w.NamespaceName))); 126 | break; 127 | // 128 | case "sz": 129 | formatting.Size = Int32.Parse( 130 | option.GetAttribute(XName.Get("val", DocX.w.NamespaceName))) / 2; 131 | break; 132 | 133 | 134 | case "rFonts": 135 | formatting.FontFamily = 136 | new Font( 137 | option.GetAttribute(XName.Get("cs", DocX.w.NamespaceName), null) ?? 138 | option.GetAttribute(XName.Get("ascii", DocX.w.NamespaceName), null) ?? 139 | option.GetAttribute(XName.Get("hAnsi", DocX.w.NamespaceName), null) ?? 140 | option.GetAttribute(XName.Get("eastAsia", DocX.w.NamespaceName))); 141 | break; 142 | case "color" : 143 | try 144 | { 145 | string color = option.GetAttribute(XName.Get("val", DocX.w.NamespaceName)); 146 | formatting.FontColor = System.Drawing.ColorTranslator.FromHtml(string.Format("#{0}", color)); 147 | } 148 | catch { } 149 | break; 150 | case "vanish": formatting.hidden = true; break; 151 | case "b": formatting.Bold = true; break; 152 | case "i": formatting.Italic = true; break; 153 | case "u": formatting.UnderlineStyle = HelperFunctions.GetUnderlineStyle(option.GetAttribute(XName.Get("val", DocX.w.NamespaceName))); break; 154 | case "vertAlign": 155 | var script = option.GetAttribute(XName.Get("val", DocX.w.NamespaceName), null); 156 | formatting.Script = (Script)Enum.Parse(typeof(Script), script); 157 | break; 158 | default: break; 159 | } 160 | } 161 | 162 | 163 | return formatting; 164 | } 165 | 166 | internal XElement Xml 167 | { 168 | get 169 | { 170 | rPr = new XElement(XName.Get("rPr", DocX.w.NamespaceName)); 171 | 172 | if (language != null) 173 | rPr.Add(new XElement(XName.Get("lang", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), language.Name))); 174 | 175 | if(spacing.HasValue) 176 | rPr.Add(new XElement(XName.Get("spacing", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), spacing.Value * 20))); 177 | 178 | if(position.HasValue) 179 | rPr.Add(new XElement(XName.Get("position", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), position.Value * 2))); 180 | 181 | if (kerning.HasValue) 182 | rPr.Add(new XElement(XName.Get("kern", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), kerning.Value * 2))); 183 | 184 | if (percentageScale.HasValue) 185 | rPr.Add(new XElement(XName.Get("w", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), percentageScale))); 186 | 187 | if (fontFamily != null) 188 | { 189 | rPr.Add 190 | ( 191 | new XElement 192 | ( 193 | XName.Get("rFonts", DocX.w.NamespaceName), 194 | new XAttribute(XName.Get("ascii", DocX.w.NamespaceName), fontFamily.Name), 195 | new XAttribute(XName.Get("hAnsi", DocX.w.NamespaceName), fontFamily.Name), // Added by Maurits Elbers to support non-standard characters. See http://docx.codeplex.com/Thread/View.aspx?ThreadId=70097&ANCHOR#Post453865 196 | new XAttribute(XName.Get("cs", DocX.w.NamespaceName), fontFamily.Name) // Added by Maurits Elbers to support non-standard characters. See http://docx.codeplex.com/Thread/View.aspx?ThreadId=70097&ANCHOR#Post453865 197 | ) 198 | ); 199 | } 200 | 201 | if (hidden.HasValue && hidden.Value) 202 | rPr.Add(new XElement(XName.Get("vanish", DocX.w.NamespaceName))); 203 | 204 | if (bold.HasValue && bold.Value) 205 | rPr.Add(new XElement(XName.Get("b", DocX.w.NamespaceName))); 206 | 207 | if (italic.HasValue && italic.Value) 208 | rPr.Add(new XElement(XName.Get("i", DocX.w.NamespaceName))); 209 | 210 | if (underlineStyle.HasValue) 211 | { 212 | switch (underlineStyle) 213 | { 214 | case Novacode.UnderlineStyle.none: 215 | break; 216 | case Novacode.UnderlineStyle.singleLine: 217 | rPr.Add(new XElement(XName.Get("u", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), "single"))); 218 | break; 219 | case Novacode.UnderlineStyle.doubleLine: 220 | rPr.Add(new XElement(XName.Get("u", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), "double"))); 221 | break; 222 | default: 223 | rPr.Add(new XElement(XName.Get("u", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), underlineStyle.ToString()))); 224 | break; 225 | } 226 | } 227 | 228 | if(underlineColor.HasValue) 229 | { 230 | // If an underlineColor has been set but no underlineStyle has been set 231 | if (underlineStyle == Novacode.UnderlineStyle.none) 232 | { 233 | // Set the underlineStyle to the default 234 | underlineStyle = Novacode.UnderlineStyle.singleLine; 235 | rPr.Add(new XElement(XName.Get("u", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), "single"))); 236 | } 237 | 238 | rPr.Element(XName.Get("u", DocX.w.NamespaceName)).Add(new XAttribute(XName.Get("color", DocX.w.NamespaceName), underlineColor.Value.ToHex())); 239 | } 240 | 241 | if (strikethrough.HasValue) 242 | { 243 | switch (strikethrough) 244 | { 245 | case Novacode.StrikeThrough.none: 246 | break; 247 | case Novacode.StrikeThrough.strike: 248 | rPr.Add(new XElement(XName.Get("strike", DocX.w.NamespaceName))); 249 | break; 250 | case Novacode.StrikeThrough.doubleStrike: 251 | rPr.Add(new XElement(XName.Get("dstrike", DocX.w.NamespaceName))); 252 | break; 253 | default: 254 | break; 255 | } 256 | } 257 | 258 | if (script.HasValue) 259 | { 260 | switch (script) 261 | { 262 | case Novacode.Script.none: 263 | break; 264 | default: 265 | rPr.Add(new XElement(XName.Get("vertAlign", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), script.ToString()))); 266 | break; 267 | } 268 | } 269 | 270 | if (size.HasValue) 271 | { 272 | rPr.Add(new XElement(XName.Get("sz", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), (size * 2).ToString()))); 273 | rPr.Add(new XElement(XName.Get("szCs", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), (size * 2).ToString()))); 274 | } 275 | 276 | if(fontColor.HasValue) 277 | rPr.Add(new XElement(XName.Get("color", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), fontColor.Value.ToHex()))); 278 | 279 | if (highlight.HasValue) 280 | { 281 | switch (highlight) 282 | { 283 | case Novacode.Highlight.none: 284 | break; 285 | default: 286 | rPr.Add(new XElement(XName.Get("highlight", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), highlight.ToString()))); 287 | break; 288 | } 289 | } 290 | 291 | if (capsStyle.HasValue) 292 | { 293 | switch (capsStyle) 294 | { 295 | case Novacode.CapsStyle.none: 296 | break; 297 | default: 298 | rPr.Add(new XElement(XName.Get(capsStyle.ToString(), DocX.w.NamespaceName))); 299 | break; 300 | } 301 | } 302 | 303 | if (misc.HasValue) 304 | { 305 | switch (misc) 306 | { 307 | case Novacode.Misc.none: 308 | break; 309 | case Novacode.Misc.outlineShadow: 310 | rPr.Add(new XElement(XName.Get("outline", DocX.w.NamespaceName))); 311 | rPr.Add(new XElement(XName.Get("shadow", DocX.w.NamespaceName))); 312 | break; 313 | case Novacode.Misc.engrave: 314 | rPr.Add(new XElement(XName.Get("imprint", DocX.w.NamespaceName))); 315 | break; 316 | default: 317 | rPr.Add(new XElement(XName.Get(misc.ToString(), DocX.w.NamespaceName))); 318 | break; 319 | } 320 | } 321 | 322 | return rPr; 323 | } 324 | } 325 | 326 | /// 327 | /// This formatting will apply Bold. 328 | /// 329 | public bool? Bold { get { return bold; } set { bold = value;} } 330 | 331 | /// 332 | /// This formatting will apply Italic. 333 | /// 334 | public bool? Italic { get { return italic; } set { italic = value; } } 335 | 336 | /// 337 | /// This formatting will apply StrickThrough. 338 | /// 339 | public StrikeThrough? StrikeThrough { get { return strikethrough; } set { strikethrough = value; } } 340 | 341 | /// 342 | /// The script that this formatting should be, normal, superscript or subscript. 343 | /// 344 | public Script? Script { get { return script; } set { script = value; } } 345 | 346 | /// 347 | /// The Size of this text, must be between 0 and 1638. 348 | /// 349 | public double? Size 350 | { 351 | get { return size; } 352 | 353 | set 354 | { 355 | double? temp = value * 2; 356 | 357 | if (temp - (int)temp == 0) 358 | { 359 | if(value > 0 && value < 1639) 360 | size = value; 361 | else 362 | throw new ArgumentException("Size", "Value must be in the range 0 - 1638"); 363 | } 364 | 365 | else 366 | throw new ArgumentException("Size", "Value must be either a whole or half number, examples: 32, 32.5"); 367 | } 368 | } 369 | 370 | /// 371 | /// Percentage scale must be one of the following values 200, 150, 100, 90, 80, 66, 50 or 33. 372 | /// 373 | public int? PercentageScale 374 | { 375 | get { return percentageScale; } 376 | 377 | set 378 | { 379 | if ((new int?[] { 200, 150, 100, 90, 80, 66, 50, 33 }).Contains(value)) 380 | percentageScale = value; 381 | else 382 | throw new ArgumentOutOfRangeException("PercentageScale", "Value must be one of the following: 200, 150, 100, 90, 80, 66, 50 or 33"); 383 | } 384 | } 385 | 386 | /// 387 | /// 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. 388 | /// 389 | public int? Kerning 390 | { 391 | get { return kerning; } 392 | 393 | set 394 | { 395 | if(new int?[] {8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72}.Contains(value)) 396 | kerning = value; 397 | else 398 | 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"); 399 | } 400 | } 401 | 402 | /// 403 | /// Text position must be in the range (-1585 - 1585). 404 | /// 405 | public int? Position 406 | { 407 | get { return position; } 408 | 409 | set 410 | { 411 | if (value > -1585 && value < 1585) 412 | position = value; 413 | else 414 | throw new ArgumentOutOfRangeException("Position", "Value must be in the range -1585 - 1585"); 415 | } 416 | } 417 | 418 | /// 419 | /// Text spacing must be in the range (-1585 - 1585). 420 | /// 421 | public double? Spacing 422 | { 423 | get { return spacing; } 424 | 425 | set 426 | { 427 | double? temp = value * 20; 428 | 429 | if (temp - (int)temp == 0) 430 | { 431 | if (value > -1585 && value < 1585) 432 | spacing = value; 433 | else 434 | throw new ArgumentException("Spacing", "Value must be in the range: -1584 - 1584"); 435 | } 436 | 437 | else 438 | throw new ArgumentException("Spacing", "Value must be either a whole or acurate to one decimal, examples: 32, 32.1, 32.2, 32.9"); 439 | } 440 | } 441 | 442 | /// 443 | /// The colour of the text. 444 | /// 445 | public Color? FontColor { get { return fontColor; } set { fontColor = value; } } 446 | 447 | /// 448 | /// Highlight colour. 449 | /// 450 | public Highlight? Highlight { get { return highlight; } set { highlight = value; } } 451 | 452 | /// 453 | /// The Underline style that this formatting applies. 454 | /// 455 | public UnderlineStyle? UnderlineStyle { get { return underlineStyle; } set { underlineStyle = value; } } 456 | 457 | /// 458 | /// The underline colour. 459 | /// 460 | public Color? UnderlineColor { get { return underlineColor; } set { underlineColor = value; } } 461 | 462 | /// 463 | /// Misc settings. 464 | /// 465 | public Misc? Misc { get { return misc; } set { misc = value; } } 466 | 467 | /// 468 | /// Is this text hidden or visible. 469 | /// 470 | public bool? Hidden { get { return hidden; } set { hidden = value; } } 471 | 472 | /// 473 | /// Capitalization style. 474 | /// 475 | public CapsStyle? CapsStyle { get { return capsStyle; } set { capsStyle = value; } } 476 | 477 | /// 478 | /// The font family of this formatting. 479 | /// 480 | /// 484 | public Font FontFamily { get { return fontFamily; } set { fontFamily = value; } } 485 | 486 | public int CompareTo(object obj) 487 | { 488 | Formatting other = (Formatting)obj; 489 | 490 | if(other.hidden != this.hidden) 491 | return -1; 492 | 493 | if(other.bold != this.bold) 494 | return -1; 495 | 496 | if(other.italic != this.italic) 497 | return -1; 498 | 499 | if(other.strikethrough != this.strikethrough) 500 | return -1; 501 | 502 | if(other.script != this.script) 503 | return -1; 504 | 505 | if(other.highlight != this.highlight) 506 | return -1; 507 | 508 | if(other.size != this.size) 509 | return -1; 510 | 511 | if(other.fontColor != this.fontColor) 512 | return -1; 513 | 514 | if(other.underlineColor != this.underlineColor) 515 | return -1; 516 | 517 | if(other.underlineStyle != this.underlineStyle) 518 | return -1; 519 | 520 | if(other.misc != this.misc) 521 | return -1; 522 | 523 | if(other.capsStyle != this.capsStyle) 524 | return -1; 525 | 526 | if(other.fontFamily != this.fontFamily) 527 | return -1; 528 | 529 | if(other.percentageScale != this.percentageScale) 530 | return -1; 531 | 532 | if(other.kerning != this.kerning) 533 | return -1; 534 | 535 | if(other.position != this.position) 536 | return -1; 537 | 538 | if(other.spacing != this.spacing) 539 | return -1; 540 | 541 | if (!other.language.Equals(this.language)) 542 | return -1; 543 | 544 | return 0; 545 | } 546 | } 547 | } 548 | -------------------------------------------------------------------------------- /src/DocXCore/Header.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Xml.Linq; 5 | using System.IO.Packaging; 6 | using System.Collections.ObjectModel; 7 | 8 | namespace Novacode 9 | { 10 | public class Header : Container, IParagraphContainer 11 | { 12 | public bool PageNumbers 13 | { 14 | get 15 | { 16 | return false; 17 | } 18 | 19 | set 20 | { 21 | XElement e = XElement.Parse 22 | (@" 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 1 42 | 43 | 44 | 45 | 46 | " 47 | ); 48 | 49 | Xml.AddFirst(e); 50 | 51 | PageNumberParagraph = new Paragraph(Document, e.Descendants(XName.Get("p", DocX.w.NamespaceName)).SingleOrDefault(), 0); 52 | } 53 | } 54 | 55 | public Paragraph PageNumberParagraph; 56 | 57 | internal Header(DocX document, XElement xml, PackagePart mainPart):base(document, xml) 58 | { 59 | this.mainPart = mainPart; 60 | } 61 | 62 | public override Paragraph InsertParagraph() 63 | { 64 | Paragraph p = base.InsertParagraph(); 65 | p.PackagePart = mainPart; 66 | return p; 67 | } 68 | 69 | public override Paragraph InsertParagraph(int index, string text, bool trackChanges) 70 | { 71 | Paragraph p = base.InsertParagraph(index, text, trackChanges); 72 | p.PackagePart = mainPart; 73 | return p; 74 | } 75 | 76 | public override Paragraph InsertParagraph(Paragraph p) 77 | { 78 | p.PackagePart = mainPart; 79 | return base.InsertParagraph(p); 80 | } 81 | 82 | public override Paragraph InsertParagraph(int index, Paragraph p) 83 | { 84 | p.PackagePart = mainPart; 85 | return base.InsertParagraph(index, p); 86 | } 87 | 88 | public override Paragraph InsertParagraph(int index, string text, bool trackChanges, Formatting formatting) 89 | { 90 | Paragraph p = base.InsertParagraph(index, text, trackChanges, formatting); 91 | p.PackagePart = mainPart; 92 | return p; 93 | } 94 | 95 | public override Paragraph InsertParagraph(string text) 96 | { 97 | Paragraph p = base.InsertParagraph(text); 98 | p.PackagePart = mainPart; 99 | return p; 100 | } 101 | 102 | public override Paragraph InsertParagraph(string text, bool trackChanges) 103 | { 104 | Paragraph p = base.InsertParagraph(text, trackChanges); 105 | p.PackagePart = mainPart; 106 | return p; 107 | } 108 | 109 | public override Paragraph InsertParagraph(string text, bool trackChanges, Formatting formatting) 110 | { 111 | Paragraph p = base.InsertParagraph(text, trackChanges, formatting); 112 | p.PackagePart = mainPart; 113 | 114 | return p; 115 | } 116 | 117 | public override Paragraph InsertEquation(String equation) 118 | { 119 | Paragraph p = base.InsertEquation(equation); 120 | p.PackagePart = mainPart; 121 | return p; 122 | } 123 | 124 | 125 | public override ReadOnlyCollection Paragraphs 126 | { 127 | get 128 | { 129 | ReadOnlyCollection l = base.Paragraphs; 130 | foreach (var paragraph in l) 131 | { 132 | paragraph.mainPart = mainPart; 133 | } 134 | return l; 135 | } 136 | } 137 | 138 | public override List
Tables 139 | { 140 | get 141 | { 142 | List
l = base.Tables; 143 | l.ForEach(x => x.mainPart = mainPart); 144 | return l; 145 | } 146 | } 147 | 148 | public List Images 149 | { 150 | get 151 | { 152 | PackageRelationshipCollection imageRelationships = mainPart.GetRelationshipsByType(DocX.relationshipImage); 153 | if (imageRelationships.Count() > 0) 154 | { 155 | return 156 | ( 157 | from i in imageRelationships 158 | select new Image(Document, i) 159 | ).ToList(); 160 | } 161 | 162 | return new List(); 163 | } 164 | } 165 | public new Table InsertTable(int rowCount, int columnCount) 166 | { 167 | if (rowCount < 1 || columnCount < 1) 168 | throw new ArgumentOutOfRangeException("Row and Column count must be greater than zero."); 169 | 170 | Table t = base.InsertTable(rowCount, columnCount); 171 | t.mainPart = mainPart; 172 | return t; 173 | } 174 | public new Table InsertTable(int index, Table t) 175 | { 176 | Table t2 = base.InsertTable(index, t); 177 | t2.mainPart = mainPart; 178 | return t2; 179 | } 180 | public new Table InsertTable(Table t) 181 | { 182 | t = base.InsertTable(t); 183 | t.mainPart = mainPart; 184 | return t; 185 | } 186 | public new Table InsertTable(int index, int rowCount, int columnCount) 187 | { 188 | if (rowCount < 1 || columnCount < 1) 189 | throw new ArgumentOutOfRangeException("Row and Column count must be greater than zero."); 190 | 191 | Table t = base.InsertTable(index, rowCount, columnCount); 192 | t.mainPart = mainPart; 193 | return t; 194 | } 195 | 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /src/DocXCore/Headers.cs: -------------------------------------------------------------------------------- 1 | namespace Novacode 2 | { 3 | public class Headers 4 | { 5 | internal Headers() 6 | { 7 | } 8 | 9 | public Header odd; 10 | public Header even; 11 | public Header first; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/DocXCore/Help/DocX v1.0.0.10 - Documentation.chm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocXCore/Help/DocX v1.0.0.10 - Documentation.chm -------------------------------------------------------------------------------- /src/DocXCore/Help/Read Me.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocXCore/Help/Read Me.docx -------------------------------------------------------------------------------- /src/DocXCore/Hyperlink.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Xml.Linq; 6 | using System.IO.Packaging; 7 | 8 | namespace Novacode 9 | { 10 | /// 11 | /// Represents a Hyperlink in a document. 12 | /// 13 | public class Hyperlink: DocXElement 14 | { 15 | internal Uri uri; 16 | internal String text; 17 | 18 | internal Dictionary hyperlink_rels; 19 | internal int type; 20 | internal String id; 21 | internal XElement instrText; 22 | internal List runs; 23 | 24 | /// 25 | /// Remove a Hyperlink from this Paragraph only. 26 | /// 27 | /// 28 | /// 29 | /// // Create a document. 30 | /// using (DocX document = DocX.Create(@"Test.docx")) 31 | /// { 32 | /// // Add a hyperlink to this document. 33 | /// Hyperlink h = document.AddHyperlink("link", new Uri("http://www.google.com")); 34 | /// 35 | /// // Add a Paragraph to this document and insert the hyperlink 36 | /// Paragraph p1 = document.InsertParagraph(); 37 | /// p1.Append("This is a cool ").AppendHyperlink(h).Append(" ."); 38 | /// 39 | /// /* 40 | /// * Remove the hyperlink from this Paragraph only. 41 | /// * Note a reference to the hyperlink will still exist in the document and it can thus be reused. 42 | /// */ 43 | /// p1.Hyperlinks[0].Remove(); 44 | /// 45 | /// // Add a new Paragraph to this document and reuse the hyperlink h. 46 | /// Paragraph p2 = document.InsertParagraph(); 47 | /// p2.Append("This is the same cool ").AppendHyperlink(h).Append(" ."); 48 | /// 49 | /// document.Save(); 50 | /// }// Release this document from memory. 51 | /// 52 | /// 53 | public void Remove() 54 | { 55 | Xml.Remove(); 56 | } 57 | 58 | /// 59 | /// Change the Text of a Hyperlink. 60 | /// 61 | /// 62 | /// Change the Text of a Hyperlink. 63 | /// 64 | /// // Create a document. 65 | /// using (DocX document = DocX.Load(@"Test.docx")) 66 | /// { 67 | /// // Get all of the hyperlinks in this document 68 | /// List<Hyperlink> hyperlinks = document.Hyperlinks; 69 | /// 70 | /// // Change the first hyperlinks text and Uri 71 | /// Hyperlink h0 = hyperlinks[0]; 72 | /// h0.Text = "DocX"; 73 | /// h0.Uri = new Uri("http://docx.codeplex.com"); 74 | /// 75 | /// // Save this document. 76 | /// document.Save(); 77 | /// } 78 | /// 79 | /// 80 | public string Text 81 | { 82 | get 83 | { 84 | return this.text; 85 | } 86 | 87 | set 88 | { 89 | XElement rPr = 90 | new XElement 91 | ( 92 | DocX.w + "rPr", 93 | new XElement 94 | ( 95 | DocX.w + "rStyle", 96 | new XAttribute(DocX.w + "val", "Hyperlink") 97 | ) 98 | ); 99 | 100 | // Format and add the new text. 101 | List newRuns = HelperFunctions.FormatInput(value, rPr); 102 | 103 | if (type == 0) 104 | { 105 | // Get all the runs in this Text. 106 | var runs = from r in Xml.Elements() 107 | where r.Name.LocalName == "r" 108 | select r; 109 | 110 | // Remove each run. 111 | for (int i = 0; i < runs.Count(); i++) 112 | runs.Remove(); 113 | 114 | Xml.Add(newRuns); 115 | } 116 | 117 | else 118 | { 119 | XElement separate = XElement.Parse(@" 120 | 121 | 122 | "); 123 | 124 | XElement end = XElement.Parse(@" 125 | 126 | 127 | "); 128 | 129 | runs.Last().AddAfterSelf(separate, newRuns, end); 130 | runs.ForEach(r => r.Remove()); 131 | } 132 | 133 | this.text = value; 134 | } 135 | } 136 | 137 | /// 138 | /// Change the Uri of a Hyperlink. 139 | /// 140 | /// 141 | /// Change the Uri of a Hyperlink. 142 | /// 143 | /// hyperlinks = document.Hyperlinks; 149 | /// 150 | /// // Change the first hyperlinks text and Uri 151 | /// Hyperlink h0 = hyperlinks[0]; 152 | /// h0.Text = "DocX"; 153 | /// h0.Uri = new Uri("http://docx.codeplex.com"); 154 | /// 155 | /// // Save this document. 156 | /// document.Save(); 157 | /// } 158 | /// ]]> 159 | /// 160 | /// 161 | public Uri Uri 162 | { 163 | get 164 | { 165 | if (type == 0 && id != String.Empty) 166 | { 167 | PackageRelationship r = mainPart.GetRelationship(id); 168 | return r.TargetUri; 169 | } 170 | 171 | return this.uri; 172 | } 173 | 174 | set 175 | { 176 | if (type == 0) 177 | { 178 | PackageRelationship r = mainPart.GetRelationship(id); 179 | 180 | // Get all of the information about this relationship. 181 | TargetMode r_tm = r.TargetMode; 182 | string r_rt = r.RelationshipType; 183 | string r_id = r.Id; 184 | 185 | // Delete the relationship 186 | mainPart.DeleteRelationship(r_id); 187 | mainPart.CreateRelationship(value, r_tm, r_rt, r_id); 188 | } 189 | 190 | else 191 | { 192 | instrText.Value = "HYPERLINK " + "\"" + value + "\""; 193 | } 194 | 195 | this.uri = value; 196 | } 197 | } 198 | 199 | internal Hyperlink(DocX document, PackagePart mainPart, XElement i): base(document, i) 200 | { 201 | this.type = 0; 202 | this.id = i.Attribute(XName.Get("id", DocX.r.NamespaceName)).Value; 203 | 204 | StringBuilder sb = new StringBuilder(); 205 | HelperFunctions.GetTextRecursive(i, ref sb); 206 | this.text = sb.ToString(); 207 | } 208 | 209 | internal Hyperlink(DocX document, XElement instrText, List runs) : base(document, null) 210 | { 211 | this.type = 1; 212 | this.instrText = instrText; 213 | this.runs = runs; 214 | 215 | try 216 | { 217 | int start = instrText.Value.IndexOf("HYPERLINK \"") + "HYPERLINK \"".Length; 218 | int end = instrText.Value.IndexOf("\"", start); 219 | if (start != -1 && end != -1) 220 | { 221 | this.uri = new Uri(instrText.Value.Substring(start, end - start), UriKind.Absolute); 222 | 223 | StringBuilder sb = new StringBuilder(); 224 | HelperFunctions.GetTextRecursive(new XElement(XName.Get("temp", DocX.w.NamespaceName), runs), ref sb); 225 | this.text = sb.ToString(); 226 | } 227 | } 228 | 229 | catch (Exception e){throw e;} 230 | } 231 | } 232 | } 233 | -------------------------------------------------------------------------------- /src/DocXCore/IContentContainer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.ObjectModel; 2 | 3 | namespace Novacode 4 | { 5 | interface IContentContainer 6 | { 7 | ReadOnlyCollection Paragraphs { get; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/DocXCore/IParagraphContainer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.ObjectModel; 2 | 3 | namespace Novacode 4 | { 5 | public interface IParagraphContainer 6 | { 7 | ReadOnlyCollection Paragraphs { get; } 8 | } 9 | } -------------------------------------------------------------------------------- /src/DocXCore/Image.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO.Packaging; 3 | using System.IO; 4 | 5 | namespace Novacode 6 | { 7 | /// 8 | /// Represents an Image embedded in a document. 9 | /// 10 | public class Image 11 | { 12 | /// 13 | /// A unique id which identifies this Image. 14 | /// 15 | private string id; 16 | private DocX document; 17 | internal PackageRelationship pr; 18 | 19 | public Stream GetStream(FileMode mode, FileAccess access) 20 | { 21 | string temp = pr.SourceUri.OriginalString; 22 | string start = temp.Remove(temp.LastIndexOf('/')); 23 | string end = pr.TargetUri.OriginalString; 24 | string full = end.Contains(start) ? end : start + "/" + end; 25 | 26 | return (new PackagePartStream(document.package.GetPart(new Uri(full, UriKind.Relative)).GetStream(mode, access))); 27 | } 28 | 29 | /// 30 | /// Returns the id of this Image. 31 | /// 32 | public string Id 33 | { 34 | get {return id;} 35 | } 36 | 37 | internal Image(DocX document, PackageRelationship pr) 38 | { 39 | this.document = document; 40 | this.pr = pr; 41 | this.id = pr.Id; 42 | } 43 | 44 | /// 45 | /// Add an image to a document, create a custom view of that image (picture) and then insert it into a Paragraph using append. 46 | /// 47 | /// 48 | /// 49 | /// Add an image to a document, create a custom view of that image (picture) and then insert it into a Paragraph using append. 50 | /// 51 | /// using (DocX document = DocX.Create("Test.docx")) 52 | /// { 53 | /// // Add an image to the document. 54 | /// Image i = document.AddImage(@"Image.jpg"); 55 | /// 56 | /// // Create a picture i.e. (A custom view of an image) 57 | /// Picture p = i.CreatePicture(); 58 | /// p.FlipHorizontal = true; 59 | /// p.Rotation = 10; 60 | /// 61 | /// // Create a new Paragraph. 62 | /// Paragraph par = document.InsertParagraph(); 63 | /// 64 | /// // Append content to the Paragraph. 65 | /// par.Append("Here is a cool picture") 66 | /// .AppendPicture(p) 67 | /// .Append(" don't you think so?"); 68 | /// 69 | /// // Save all changes made to this document. 70 | /// document.Save(); 71 | /// } 72 | /// 73 | /// 74 | public Picture CreatePicture() 75 | { 76 | return Paragraph.CreatePicture(document, id, string.Empty, string.Empty); 77 | } 78 | public Picture CreatePicture(int height, int width) { 79 | Picture picture = Paragraph.CreatePicture(document, id, string.Empty, string.Empty); 80 | picture.Height = height; 81 | picture.Width = width; 82 | return picture; 83 | } 84 | 85 | /// 86 | /// Returns the name of the image file. 87 | /// 88 | public string FileName 89 | { 90 | get 91 | { 92 | return Path.GetFileName(this.pr.TargetUri.ToString()); 93 | } 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/DocXCore/License/License.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | Microsoft Public License (Ms-PL)

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.

1. Definitions

The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law.

A "contribution" is the original software, or any additions or changes to the software.

A "contributor" is any person that distributes its contribution under this license.

"Licensed patents" are a contributor's patent claims that read directly on its contribution.

2. Grant of Rights

(A) 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.

(B) 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/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.

3. Conditions and Limitations

(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.

(B) 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.

(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.

(D) 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.

(E) The software is licensed "as-is." 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.
5 |
6 | 7 | -------------------------------------------------------------------------------- /src/DocXCore/List.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Xml.Linq; 5 | 6 | namespace Novacode 7 | { 8 | /// 9 | /// Represents a List in a document. 10 | /// 11 | public class List : InsertBeforeOrAfter 12 | { 13 | /// 14 | /// This is a list of paragraphs that will be added to the document 15 | /// when the list is inserted into the document. 16 | /// The paragraph needs a numPr defined to be in this items collection. 17 | /// 18 | public List Items { get; private set; } 19 | /// 20 | /// The numId used to reference the list settings in the numbering.xml 21 | /// 22 | public int NumId { get; private set; } 23 | /// 24 | /// The ListItemType (bullet or numbered) of the list. 25 | /// 26 | public ListItemType? ListType { get; private set; } 27 | 28 | internal List(DocX document, XElement xml) 29 | : base(document, xml) 30 | { 31 | Items = new List(); 32 | ListType = null; 33 | } 34 | 35 | /// 36 | /// Adds an item to the list. 37 | /// 38 | /// 39 | /// 40 | /// Throws an InvalidOperationException if the item cannot be added to the list. 41 | /// 42 | public void AddItem(Paragraph paragraph) 43 | { 44 | if (paragraph.IsListItem) 45 | { 46 | var numIdNode = paragraph.Xml.Descendants().First(s => s.Name.LocalName == "numId"); 47 | var numId = Int32.Parse(numIdNode.Attribute(DocX.w + "val").Value); 48 | 49 | if (CanAddListItem(paragraph)) 50 | { 51 | NumId = numId; 52 | Items.Add(paragraph); 53 | } 54 | else 55 | throw new InvalidOperationException("New list items can only be added to this list if they are have the same numId."); 56 | } 57 | } 58 | 59 | public void AddItemWithStartValue(Paragraph paragraph, int start) 60 | { 61 | //TODO: Update the numbering 62 | UpdateNumberingForLevelStartNumber(int.Parse(paragraph.IndentLevel.ToString()), start); 63 | if (ContainsLevel(start)) 64 | throw new InvalidOperationException("Cannot add a paragraph with a start value if another element already exists in this list with that level."); 65 | AddItem(paragraph); 66 | } 67 | 68 | private void UpdateNumberingForLevelStartNumber(int iLevel, int start) 69 | { 70 | var abstractNum = GetAbstractNum(NumId); 71 | var level = abstractNum.Descendants().First(el => el.Name.LocalName == "lvl" && el.GetAttribute(DocX.w + "ilvl") == iLevel.ToString()); 72 | level.Descendants().First(el => el.Name.LocalName == "start").SetAttributeValue(DocX.w + "val", start); 73 | } 74 | 75 | /// 76 | /// Determine if it is able to add the item to the list 77 | /// 78 | /// 79 | /// 80 | /// Return true if AddItem(...) will succeed with the given paragraph. 81 | /// 82 | public bool CanAddListItem(Paragraph paragraph) 83 | { 84 | if (paragraph.IsListItem) 85 | { 86 | //var lvlNode = paragraph.Xml.Descendants().First(s => s.Name.LocalName == "ilvl"); 87 | var numIdNode = paragraph.Xml.Descendants().First(s => s.Name.LocalName == "numId"); 88 | var numId = Int32.Parse(numIdNode.Attribute(DocX.w + "val").Value); 89 | 90 | //Level = Int32.Parse(lvlNode.Attribute(DocX.w + "val").Value); 91 | if (NumId == 0 || (numId == NumId && numId > 0)) 92 | { 93 | return true; 94 | } 95 | } 96 | return false; 97 | } 98 | 99 | public bool ContainsLevel(int ilvl) 100 | { 101 | return Items.Any(i => i.ParagraphNumberProperties.Descendants().First(el => el.Name.LocalName == "ilvl").Value == ilvl.ToString()); 102 | } 103 | 104 | internal void CreateNewNumberingNumId(int level = 0, ListItemType listType = ListItemType.Numbered, int? startNumber = null, bool continueNumbering = false) 105 | { 106 | ValidateDocXNumberingPartExists(); 107 | if (Document.numbering.Root == null) 108 | { 109 | throw new InvalidOperationException("Numbering section did not instantiate properly."); 110 | } 111 | 112 | ListType = listType; 113 | 114 | var numId = GetMaxNumId() + 1; 115 | var abstractNumId = GetMaxAbstractNumId() + 1; 116 | 117 | XDocument listTemplate; 118 | switch (listType) 119 | { 120 | case ListItemType.Bulleted: 121 | listTemplate = HelperFunctions.DecompressXMLResource("Novacode.Resources.numbering.default_bullet_abstract.xml.gz"); 122 | break; 123 | case ListItemType.Numbered: 124 | listTemplate = HelperFunctions.DecompressXMLResource("Novacode.Resources.numbering.default_decimal_abstract.xml.gz"); 125 | break; 126 | default: 127 | throw new InvalidOperationException(string.Format("Unable to deal with ListItemType: {0}.", listType.ToString())); 128 | } 129 | 130 | var abstractNumTemplate = listTemplate.Descendants().Single(d => d.Name.LocalName == "abstractNum"); 131 | abstractNumTemplate.SetAttributeValue(DocX.w + "abstractNumId", abstractNumId); 132 | 133 | //Fixing an issue where numbering would continue from previous numbered lists. Setting startOverride assures that a numbered list starts on the provided number. 134 | //The override needs only be on level 0 as this will cascade to the rest of the list. 135 | var abstractNumXml = GetAbstractNumXml(abstractNumId, numId, startNumber, continueNumbering); 136 | 137 | var abstractNumNode = Document.numbering.Root.Descendants().LastOrDefault(xElement => xElement.Name.LocalName == "abstractNum"); 138 | var numXml = Document.numbering.Root.Descendants().LastOrDefault(xElement => xElement.Name.LocalName == "num"); 139 | 140 | if (abstractNumNode == null || numXml == null) 141 | { 142 | Document.numbering.Root.Add(abstractNumTemplate); 143 | Document.numbering.Root.Add(abstractNumXml); 144 | } 145 | else 146 | { 147 | abstractNumNode.AddAfterSelf(abstractNumTemplate); 148 | numXml.AddAfterSelf( 149 | abstractNumXml 150 | ); 151 | } 152 | 153 | NumId = numId; 154 | } 155 | 156 | private XElement GetAbstractNumXml(int abstractNumId, int numId, int? startNumber, bool continueNumbering) 157 | { 158 | //Fixing an issue where numbering would continue from previous numbered lists. Setting startOverride assures that a numbered list starts on the provided number. 159 | //The override needs only be on level 0 as this will cascade to the rest of the list. 160 | var startOverride = new XElement(XName.Get("startOverride", DocX.w.NamespaceName), new XAttribute(DocX.w + "val", startNumber ?? 1)); 161 | var lvlOverride = new XElement(XName.Get("lvlOverride", DocX.w.NamespaceName), new XAttribute(DocX.w + "ilvl", 0), startOverride); 162 | var abstractNumIdElement = new XElement(XName.Get("abstractNumId", DocX.w.NamespaceName), new XAttribute(DocX.w + "val", abstractNumId)); 163 | return continueNumbering 164 | ? new XElement(XName.Get("num", DocX.w.NamespaceName), new XAttribute(DocX.w + "numId", numId), abstractNumIdElement) 165 | : new XElement(XName.Get("num", DocX.w.NamespaceName), new XAttribute(DocX.w + "numId", numId), abstractNumIdElement, lvlOverride); 166 | } 167 | 168 | /// 169 | /// Method to determine the last numId for a list element. 170 | /// Also useful for determining the next numId to use for inserting a new list element into the document. 171 | /// 172 | /// 173 | /// 0 if there are no elements in the list already. 174 | /// Increment the return for the next valid value of a new list element. 175 | /// 176 | private int GetMaxNumId() 177 | { 178 | const int defaultValue = 0; 179 | if (Document.numbering == null) 180 | return defaultValue; 181 | 182 | var numlist = Document.numbering.Descendants().Where(d => d.Name.LocalName == "num").ToList(); 183 | if (numlist.Any()) 184 | return numlist.Attributes(DocX.w + "numId").Max(e => int.Parse(e.Value)); 185 | return defaultValue; 186 | } 187 | 188 | /// 189 | /// Method to determine the last abstractNumId for a list element. 190 | /// Also useful for determining the next abstractNumId to use for inserting a new list element into the document. 191 | /// 192 | /// 193 | /// -1 if there are no elements in the list already. 194 | /// Increment the return for the next valid value of a new list element. 195 | /// 196 | private int GetMaxAbstractNumId() 197 | { 198 | const int defaultValue = -1; 199 | 200 | if (Document.numbering == null) 201 | return defaultValue; 202 | 203 | var numlist = Document.numbering.Descendants().Where(d => d.Name.LocalName == "abstractNum").ToList(); 204 | if (numlist.Any()) 205 | { 206 | var maxAbstractNumId = numlist.Attributes(DocX.w + "abstractNumId").Max(e => int.Parse(e.Value)); 207 | return maxAbstractNumId; 208 | } 209 | return defaultValue; 210 | } 211 | 212 | /// 213 | /// Get the abstractNum definition for the given numId 214 | /// 215 | /// The numId on the pPr element 216 | /// XElement representing the requested abstractNum 217 | internal XElement GetAbstractNum(int numId) 218 | { 219 | var num = Document.numbering.Descendants().First(d => d.Name.LocalName == "num" && d.GetAttribute(DocX.w + "numId").Equals(numId.ToString())); 220 | var abstractNumId = num.Descendants().First(d => d.Name.LocalName == "abstractNumId"); 221 | return Document.numbering.Descendants() 222 | .First(d => d.Name.LocalName == "abstractNum" && d.GetAttribute(DocX.w + "abstractNumId") 223 | .Equals(abstractNumId.GetAttribute(DocX.w + "val"))); 224 | } 225 | 226 | private void ValidateDocXNumberingPartExists() 227 | { 228 | var numberingUri = new Uri("/word/numbering.xml", UriKind.Relative); 229 | 230 | // If the internal document contains no /word/numbering.xml create one. 231 | if (!Document.package.PartExists(numberingUri)) 232 | { 233 | Document.numbering = HelperFunctions.AddDefaultNumberingXml(Document.package); 234 | Document.numberingPart = Document.package.GetPart(numberingUri); 235 | } 236 | } 237 | } 238 | } 239 | -------------------------------------------------------------------------------- /src/DocXCore/NETCorePort/Color.cs: -------------------------------------------------------------------------------- 1 | namespace Novacode.NETCorePort 2 | { 3 | public class DefinedColors 4 | { 5 | public static string White => "ffffff"; 6 | public static string Transparent => "transparent"; 7 | public static string Black => "000000"; 8 | public static string Empty => null; 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/DocXCore/NETCorePort/DescriptionAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | #if NETSTANDARD1_6 4 | namespace Novacode.NETCorePort 5 | { 6 | 7 | public class DescriptionAttribute:Attribute 8 | { 9 | public DescriptionAttribute(string description) 10 | { 11 | Description = description; 12 | } 13 | 14 | public string Description { get; } 15 | } 16 | } 17 | #endif 18 | -------------------------------------------------------------------------------- /src/DocXCore/NETCorePort/StringExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace Novacode.NETCorePort 2 | { 3 | public static class StringExtensions 4 | { 5 | public static bool HasValue(this string val) 6 | { 7 | return !string.IsNullOrEmpty(val); 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/DocXCore/PackagePartStream.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace Novacode 4 | { 5 | /// 6 | /// OpenXML Isolated Storage access is not thread safe. 7 | /// Use app domain wide lock for writing. 8 | /// 9 | public class PackagePartStream : Stream 10 | { 11 | private static readonly object lockObject = new object(); 12 | 13 | private readonly Stream stream; 14 | 15 | public PackagePartStream(Stream stream) 16 | { 17 | this.stream = stream; 18 | } 19 | 20 | public override bool CanRead 21 | { 22 | get { return this.stream.CanRead; } 23 | } 24 | 25 | public override bool CanSeek 26 | { 27 | get { return this.stream.CanSeek; } 28 | } 29 | 30 | public override bool CanWrite 31 | { 32 | get { return this.stream.CanWrite; } 33 | } 34 | 35 | public override long Length 36 | { 37 | get { return this.stream.Length; } 38 | } 39 | 40 | public override long Position 41 | { 42 | get { return this.stream.Position; } 43 | set { this.stream.Position = value; } 44 | } 45 | 46 | public override long Seek(long offset, SeekOrigin origin) 47 | { 48 | return this.stream.Seek(offset, origin); 49 | } 50 | 51 | public override void SetLength(long value) 52 | { 53 | this.stream.SetLength(value); 54 | } 55 | 56 | public override int Read(byte[] buffer, int offset, int count) 57 | { 58 | return this.stream.Read(buffer, offset, count); 59 | } 60 | 61 | public override void Write(byte[] buffer, int offset, int count) 62 | { 63 | lock (lockObject) 64 | { 65 | this.stream.Write(buffer, offset, count); 66 | } 67 | } 68 | 69 | public override void Flush() 70 | { 71 | lock (lockObject) 72 | { 73 | this.stream.Flush(); 74 | } 75 | } 76 | 77 | #if NETSTANDARD1_6 78 | public void Close() 79 | { 80 | this.stream.Dispose(); 81 | } 82 | #else 83 | public override void Close() 84 | { 85 | this.stream.Close(); 86 | } 87 | #endif 88 | protected override void Dispose(bool disposing) 89 | { 90 | this.stream.Flush(); 91 | this.stream.Dispose(); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/DocXCore/PageLayout.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Xml.Linq; 3 | 4 | namespace Novacode 5 | { 6 | public class PageLayout: DocXElement 7 | { 8 | internal PageLayout(DocX document, XElement xml):base(document, xml) 9 | { 10 | 11 | } 12 | 13 | 14 | public Orientation Orientation 15 | { 16 | get 17 | { 18 | /* 19 | * Get the pgSz (page size) element for this Section, 20 | * null will be return if no such element exists. 21 | */ 22 | XElement pgSz = Xml.Element(XName.Get("pgSz", DocX.w.NamespaceName)); 23 | 24 | if (pgSz == null) 25 | return Orientation.Portrait; 26 | 27 | // Get the attribute of the pgSz element. 28 | XAttribute val = pgSz.Attribute(XName.Get("orient", DocX.w.NamespaceName)); 29 | 30 | // If val is null, this cell contains no information. 31 | if (val == null) 32 | return Orientation.Portrait; 33 | 34 | if (val.Value.Equals("Landscape", StringComparison.CurrentCultureIgnoreCase)) 35 | return Orientation.Landscape; 36 | else 37 | return Orientation.Portrait; 38 | } 39 | 40 | set 41 | { 42 | // Check if already correct value. 43 | if (Orientation == value) 44 | return; 45 | 46 | /* 47 | * Get the pgSz (page size) element for this Section, 48 | * null will be return if no such element exists. 49 | */ 50 | XElement pgSz = Xml.Element(XName.Get("pgSz", DocX.w.NamespaceName)); 51 | 52 | if (pgSz == null) 53 | { 54 | Xml.SetElementValue(XName.Get("pgSz", DocX.w.NamespaceName), string.Empty); 55 | pgSz = Xml.Element(XName.Get("pgSz", DocX.w.NamespaceName)); 56 | } 57 | 58 | pgSz.SetAttributeValue(XName.Get("orient", DocX.w.NamespaceName), value.ToString().ToLower()); 59 | 60 | if(value == Novacode.Orientation.Landscape) 61 | { 62 | pgSz.SetAttributeValue(XName.Get("w", DocX.w.NamespaceName), "16838"); 63 | pgSz.SetAttributeValue(XName.Get("h", DocX.w.NamespaceName), "11906"); 64 | } 65 | 66 | else if (value == Novacode.Orientation.Portrait) 67 | { 68 | pgSz.SetAttributeValue(XName.Get("w", DocX.w.NamespaceName), "11906"); 69 | pgSz.SetAttributeValue(XName.Get("h", DocX.w.NamespaceName), "16838"); 70 | } 71 | } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/DocXCore/Picture.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Xml.Linq; 4 | using System.IO.Packaging; 5 | 6 | namespace Novacode 7 | { 8 | /// 9 | /// Represents a Picture in this document, a Picture is a customized view of an Image. 10 | /// 11 | public class Picture: DocXElement 12 | { 13 | private const int EmusInPixel = 9525; 14 | 15 | internal Dictionary picture_rels; 16 | 17 | internal Image img; 18 | private string id; 19 | private string name; 20 | private string descr; 21 | private int cx, cy; 22 | //private string fileName; 23 | private uint rotation; 24 | private bool hFlip, vFlip; 25 | private object pictureShape; 26 | private XElement xfrm; 27 | private XElement prstGeom; 28 | 29 | /// 30 | /// Remove this Picture from this document. 31 | /// 32 | public void Remove() 33 | { 34 | Xml.Remove(); 35 | } 36 | 37 | /// 38 | /// Wraps an XElement as an Image 39 | /// 40 | /// 41 | /// The XElement i to wrap 42 | /// 43 | internal Picture(DocX document, XElement i, Image img):base(document, i) 44 | { 45 | picture_rels = new Dictionary(); 46 | 47 | this.img = img; 48 | 49 | this.id = 50 | ( 51 | from e in Xml.Descendants() 52 | where e.Name.LocalName.Equals("blip") 53 | select e.Attribute(XName.Get("embed", "http://schemas.openxmlformats.org/officeDocument/2006/relationships")).Value 54 | ).SingleOrDefault(); 55 | 56 | if (this.id == null) 57 | { 58 | this.id = 59 | ( 60 | from e in Xml.Descendants() 61 | where e.Name.LocalName.Equals("imagedata") 62 | select e.Attribute(XName.Get("id", "http://schemas.openxmlformats.org/officeDocument/2006/relationships")).Value 63 | ).SingleOrDefault(); 64 | } 65 | 66 | this.name = 67 | ( 68 | from e in Xml.Descendants() 69 | let a = e.Attribute(XName.Get("name")) 70 | where (a != null) 71 | select a.Value 72 | ).FirstOrDefault(); 73 | 74 | if (this.name == null) 75 | { 76 | this.name = 77 | ( 78 | from e in Xml.Descendants() 79 | let a = e.Attribute(XName.Get("title")) 80 | where (a != null) 81 | select a.Value 82 | ).FirstOrDefault(); 83 | } 84 | 85 | this.descr = 86 | ( 87 | from e in Xml.Descendants() 88 | let a = e.Attribute(XName.Get("descr")) 89 | where (a != null) 90 | select a.Value 91 | ).FirstOrDefault(); 92 | 93 | this.cx = 94 | ( 95 | from e in Xml.Descendants() 96 | let a = e.Attribute(XName.Get("cx")) 97 | where (a != null) 98 | select int.Parse(a.Value) 99 | ).FirstOrDefault(); 100 | 101 | if (this.cx == 0) 102 | { 103 | XAttribute style = 104 | ( 105 | from e in Xml.Descendants() 106 | let a = e.Attribute(XName.Get("style")) 107 | where (a != null) 108 | select a 109 | ).FirstOrDefault(); 110 | 111 | string fromWidth = style.Value.Substring(style.Value.IndexOf("width:") + 6); 112 | var widthInt = ((double.Parse((fromWidth.Substring(0, fromWidth.IndexOf("pt"))).Replace(".", ","))) / 72.0) * 914400; 113 | cx = System.Convert.ToInt32(widthInt); 114 | } 115 | 116 | this.cy = 117 | ( 118 | from e in Xml.Descendants() 119 | let a = e.Attribute(XName.Get("cy")) 120 | where (a != null) 121 | select int.Parse(a.Value) 122 | ).FirstOrDefault(); 123 | 124 | if (this.cy == 0) 125 | { 126 | XAttribute style = 127 | ( 128 | from e in Xml.Descendants() 129 | let a = e.Attribute(XName.Get("style")) 130 | where (a != null) 131 | select a 132 | ).FirstOrDefault(); 133 | 134 | string fromHeight = style.Value.Substring(style.Value.IndexOf("height:") + 7); 135 | var heightInt = ((double.Parse((fromHeight.Substring(0, fromHeight.IndexOf("pt"))).Replace(".", ","))) / 72.0) * 914400; 136 | cy = System.Convert.ToInt32(heightInt); 137 | } 138 | 139 | this.xfrm = 140 | ( 141 | from d in Xml.Descendants() 142 | where d.Name.LocalName.Equals("xfrm") 143 | select d 144 | ).SingleOrDefault(); 145 | 146 | this.prstGeom = 147 | ( 148 | from d in Xml.Descendants() 149 | where d.Name.LocalName.Equals("prstGeom") 150 | select d 151 | ).SingleOrDefault(); 152 | 153 | if (xfrm != null) 154 | this.rotation = xfrm.Attribute(XName.Get("rot")) == null ? 0 : uint.Parse(xfrm.Attribute(XName.Get("rot")).Value); 155 | } 156 | 157 | private void SetPictureShape(object shape) 158 | { 159 | this.pictureShape = shape; 160 | 161 | XAttribute prst = prstGeom.Attribute(XName.Get("prst")); 162 | if (prst == null) 163 | prstGeom.Add(new XAttribute(XName.Get("prst"), "rectangle")); 164 | 165 | prstGeom.Attribute(XName.Get("prst")).Value = shape.ToString(); 166 | } 167 | 168 | /// 169 | /// Set the shape of this Picture to one in the BasicShapes enumeration. 170 | /// 171 | /// A shape from the BasicShapes enumeration. 172 | public void SetPictureShape(BasicShapes shape) 173 | { 174 | SetPictureShape((object)shape); 175 | } 176 | 177 | /// 178 | /// Set the shape of this Picture to one in the RectangleShapes enumeration. 179 | /// 180 | /// A shape from the RectangleShapes enumeration. 181 | public void SetPictureShape(RectangleShapes shape) 182 | { 183 | SetPictureShape((object)shape); 184 | } 185 | 186 | /// 187 | /// Set the shape of this Picture to one in the BlockArrowShapes enumeration. 188 | /// 189 | /// A shape from the BlockArrowShapes enumeration. 190 | public void SetPictureShape(BlockArrowShapes shape) 191 | { 192 | SetPictureShape((object)shape); 193 | } 194 | 195 | /// 196 | /// Set the shape of this Picture to one in the EquationShapes enumeration. 197 | /// 198 | /// A shape from the EquationShapes enumeration. 199 | public void SetPictureShape(EquationShapes shape) 200 | { 201 | SetPictureShape((object)shape); 202 | } 203 | 204 | /// 205 | /// Set the shape of this Picture to one in the FlowchartShapes enumeration. 206 | /// 207 | /// A shape from the FlowchartShapes enumeration. 208 | public void SetPictureShape(FlowchartShapes shape) 209 | { 210 | SetPictureShape((object)shape); 211 | } 212 | 213 | /// 214 | /// Set the shape of this Picture to one in the StarAndBannerShapes enumeration. 215 | /// 216 | /// A shape from the StarAndBannerShapes enumeration. 217 | public void SetPictureShape(StarAndBannerShapes shape) 218 | { 219 | SetPictureShape((object)shape); 220 | } 221 | 222 | /// 223 | /// Set the shape of this Picture to one in the CalloutShapes enumeration. 224 | /// 225 | /// A shape from the CalloutShapes enumeration. 226 | public void SetPictureShape(CalloutShapes shape) 227 | { 228 | SetPictureShape((object)shape); 229 | } 230 | 231 | /// 232 | /// A unique id that identifies an Image embedded in this document. 233 | /// 234 | public string Id 235 | { 236 | get { return id; } 237 | } 238 | 239 | /// 240 | /// Flip this Picture Horizontally. 241 | /// 242 | public bool FlipHorizontal 243 | { 244 | get { return hFlip; } 245 | 246 | set 247 | { 248 | hFlip = value; 249 | 250 | XAttribute flipH = xfrm.Attribute(XName.Get("flipH")); 251 | if (flipH == null) 252 | xfrm.Add(new XAttribute(XName.Get("flipH"), "0")); 253 | 254 | xfrm.Attribute(XName.Get("flipH")).Value = hFlip ? "1" : "0"; 255 | } 256 | } 257 | 258 | /// 259 | /// Flip this Picture Vertically. 260 | /// 261 | public bool FlipVertical 262 | { 263 | get { return vFlip; } 264 | 265 | set 266 | { 267 | vFlip = value; 268 | 269 | XAttribute flipV = xfrm.Attribute(XName.Get("flipV")); 270 | if (flipV == null) 271 | xfrm.Add(new XAttribute(XName.Get("flipV"), "0")); 272 | 273 | xfrm.Attribute(XName.Get("flipV")).Value = vFlip ? "1" : "0"; 274 | } 275 | } 276 | 277 | /// 278 | /// The rotation in degrees of this image, actual value = value % 360 279 | /// 280 | public uint Rotation 281 | { 282 | get { return rotation / 60000; } 283 | 284 | set 285 | { 286 | rotation = (value % 360) * 60000; 287 | XElement xfrm = 288 | (from d in Xml.Descendants() 289 | where d.Name.LocalName.Equals("xfrm") 290 | select d).Single(); 291 | 292 | XAttribute rot = xfrm.Attribute(XName.Get("rot")); 293 | if(rot == null) 294 | xfrm.Add(new XAttribute(XName.Get("rot"), 0)); 295 | 296 | xfrm.Attribute(XName.Get("rot")).Value = rotation.ToString(); 297 | } 298 | } 299 | 300 | /// 301 | /// Gets or sets the name of this Image. 302 | /// 303 | public string Name 304 | { 305 | get { return name; } 306 | 307 | set 308 | { 309 | name = value; 310 | 311 | foreach (XAttribute a in Xml.Descendants().Attributes(XName.Get("name"))) 312 | a.Value = name; 313 | } 314 | } 315 | 316 | /// 317 | /// Gets or sets the description for this Image. 318 | /// 319 | public string Description 320 | { 321 | get { return descr; } 322 | 323 | set 324 | { 325 | descr = value; 326 | 327 | foreach (XAttribute a in Xml.Descendants().Attributes(XName.Get("descr"))) 328 | a.Value = descr; 329 | } 330 | } 331 | 332 | /// 333 | /// Returns the name of the image file for the picture. 334 | /// 335 | public string FileName 336 | { 337 | get 338 | { 339 | return img.FileName; 340 | } 341 | } 342 | 343 | /// 344 | /// Get or sets the Width of this Image. 345 | /// 346 | public int Width 347 | { 348 | get { return cx / EmusInPixel; } 349 | 350 | set 351 | { 352 | cx = value * EmusInPixel; 353 | 354 | foreach (XAttribute a in Xml.Descendants().Attributes(XName.Get("cx"))) 355 | a.Value = (cx).ToString(); 356 | } 357 | } 358 | 359 | /// 360 | /// Get or sets the height of this Image. 361 | /// 362 | public int Height 363 | { 364 | get { return cy / EmusInPixel; } 365 | 366 | set 367 | { 368 | cy = value * EmusInPixel; 369 | 370 | foreach (XAttribute a in Xml.Descendants().Attributes(XName.Get("cy"))) 371 | a.Value = (cy).ToString(); 372 | } 373 | } 374 | 375 | //public void Delete() 376 | //{ 377 | // // Remove xml 378 | // i.Remove(); 379 | 380 | // // Rebuild the image collection for this paragraph 381 | // // Requires that every Image have a link to its paragraph 382 | 383 | //} 384 | } 385 | } 386 | -------------------------------------------------------------------------------- /src/DocXCore/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Docx")] 9 | [assembly: AssemblyDescription("A fork of the DocX Project for .NET Core")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("DocX")] 12 | [assembly: AssemblyProduct("Docx")] 13 | [assembly: AssemblyCopyright("DocX @ 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | [assembly: InternalsVisibleTo("DocX.UnitTest")] 17 | // Allow the UnitTests to get at internal stuff. 18 | [assembly: InternalsVisibleTo("UnitTests")] 19 | 20 | // Setting ComVisible to false makes the types in this assembly not visible 21 | // to COM components. If you need to access a type in this assembly from 22 | // COM, set the ComVisible attribute to true on that type. 23 | [assembly: ComVisible(false)] 24 | 25 | // The following GUID is for the ID of the typelib if this project is exposed to COM 26 | [assembly: Guid("16123f21-f3d1-47bb-ae9a-eb7c82c0f3c8")] 27 | 28 | // Version information for an assembly consists of the following four values: 29 | // 30 | // Major Version 31 | // Minor Version 32 | // Build Number 33 | // Revision 34 | // 35 | // You can specify all the values or you can default the Build and Revision Numbers 36 | // by using the '*' as shown below: 37 | // [assembly: AssemblyVersion("1.0.*")] 38 | [assembly: AssemblyVersion("1.0.0.23")] 39 | [assembly: AssemblyFileVersion("1.0.0.23")] -------------------------------------------------------------------------------- /src/DocXCore/Resources/default_styles.xml.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocXCore/Resources/default_styles.xml.gz -------------------------------------------------------------------------------- /src/DocXCore/Resources/numbering.default_bullet_abstract.xml.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocXCore/Resources/numbering.default_bullet_abstract.xml.gz -------------------------------------------------------------------------------- /src/DocXCore/Resources/numbering.default_decimal_abstract.xml.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocXCore/Resources/numbering.default_decimal_abstract.xml.gz -------------------------------------------------------------------------------- /src/DocXCore/Resources/numbering.xml.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocXCore/Resources/numbering.xml.gz -------------------------------------------------------------------------------- /src/DocXCore/Resources/styles.xml.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocXCore/Resources/styles.xml.gz -------------------------------------------------------------------------------- /src/DocXCore/Section.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Xml.Linq; 3 | 4 | namespace Novacode 5 | { 6 | public class Section : Container 7 | { 8 | 9 | public SectionBreakType SectionBreakType; 10 | 11 | internal Section(DocX document, XElement xml) : base(document, xml) 12 | { 13 | } 14 | 15 | public List SectionParagraphs { get; set; } 16 | } 17 | } -------------------------------------------------------------------------------- /src/DocXCore/TableOfContents.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using System.Xml; 5 | using System.Xml.Linq; 6 | 7 | namespace Novacode 8 | { 9 | /// 10 | /// Represents a table of contents in the document 11 | /// 12 | public class TableOfContents : DocXElement 13 | { 14 | #region TocBaseValues 15 | 16 | private const string HeaderStyle = "TOCHeading"; 17 | private const int RightTabPos = 9350; 18 | #endregion 19 | 20 | private TableOfContents(DocX document, XElement xml, string headerStyle) : base(document, xml) 21 | { 22 | AssureUpdateField(document); 23 | AssureStyles(document, headerStyle); 24 | } 25 | 26 | internal static TableOfContents CreateTableOfContents(DocX document, string title, TableOfContentsSwitches switches, string headerStyle = null, int lastIncludeLevel = 3, int? rightTabPos = null) 27 | { 28 | var reader = XmlReader.Create(new StringReader(string.Format(XmlTemplateBases.TocXmlBase, headerStyle ?? HeaderStyle, title, rightTabPos ?? RightTabPos, BuildSwitchString(switches, lastIncludeLevel)))); 29 | var xml = XElement.Load(reader); 30 | return new TableOfContents(document, xml, headerStyle); 31 | } 32 | 33 | private void AssureUpdateField(DocX document) 34 | { 35 | if (document.settings.Descendants().Any(x => x.Name.Equals(DocX.w + "updateFields"))) return; 36 | 37 | var element = new XElement(XName.Get("updateFields", DocX.w.NamespaceName), new XAttribute(DocX.w + "val", true)); 38 | document.settings.Root.Add(element); 39 | } 40 | 41 | private void AssureStyles(DocX document, string headerStyle) 42 | { 43 | if (!HasStyle(document, headerStyle, "paragraph")) 44 | { 45 | var reader = XmlReader.Create(new StringReader(string.Format(XmlTemplateBases.TocHeadingStyleBase, headerStyle ?? HeaderStyle))); 46 | var xml = XElement.Load(reader); 47 | document.styles.Root.Add(xml); 48 | } 49 | if (!HasStyle(document, "TOC1", "paragraph")) 50 | { 51 | var reader = XmlReader.Create(new StringReader(string.Format(XmlTemplateBases.TocElementStyleBase, "TOC1", "toc 1"))); 52 | var xml = XElement.Load(reader); 53 | document.styles.Root.Add(xml); 54 | } 55 | if (!HasStyle(document, "TOC2", "paragraph")) 56 | { 57 | var reader = XmlReader.Create(new StringReader(string.Format(XmlTemplateBases.TocElementStyleBase, "TOC2", "toc 2"))); 58 | var xml = XElement.Load(reader); 59 | document.styles.Root.Add(xml); 60 | } 61 | if (!HasStyle(document, "TOC3", "paragraph")) 62 | { 63 | var reader = XmlReader.Create(new StringReader(string.Format(XmlTemplateBases.TocElementStyleBase, "TOC3", "toc 3"))); 64 | var xml = XElement.Load(reader); 65 | document.styles.Root.Add(xml); 66 | } 67 | if (!HasStyle(document, "TOC4", "paragraph")) 68 | { 69 | var reader = XmlReader.Create(new StringReader(string.Format(XmlTemplateBases.TocElementStyleBase, "TOC4", "toc 4"))); 70 | var xml = XElement.Load(reader); 71 | document.styles.Root.Add(xml); 72 | } 73 | if (!HasStyle(document, "Hyperlink", "character")) 74 | { 75 | var reader = XmlReader.Create(new StringReader(string.Format(XmlTemplateBases.TocHyperLinkStyleBase))); 76 | var xml = XElement.Load(reader); 77 | document.styles.Root.Add(xml); 78 | } 79 | } 80 | 81 | private bool HasStyle(DocX document, string value, string type) 82 | { 83 | return document.styles.Descendants().Any(x => x.Name.Equals(DocX.w + "style")&& (x.Attribute(DocX.w + "type") == null || x.Attribute(DocX.w + "type").Value.Equals(type)) && x.Attribute(DocX.w + "styleId") != null && x.Attribute(DocX.w + "styleId").Value.Equals(value)); 84 | } 85 | 86 | private static string BuildSwitchString(TableOfContentsSwitches switches, int lastIncludeLevel) 87 | { 88 | var allSwitches = Enum.GetValues(typeof (TableOfContentsSwitches)).Cast(); 89 | var switchString = "TOC"; 90 | foreach (var s in allSwitches.Where(s => s != TableOfContentsSwitches.None && switches.HasFlag(s))) 91 | { 92 | switchString += " " + s.EnumDescription(); 93 | if (s == TableOfContentsSwitches.O) 94 | { 95 | switchString += string.Format(" '{0}-{1}'", 1, lastIncludeLevel); 96 | } 97 | } 98 | 99 | return switchString; 100 | } 101 | 102 | } 103 | } -------------------------------------------------------------------------------- /src/DocXCore/_BaseClasses.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO.Packaging; 3 | using System.Linq; 4 | using System.Xml.Linq; 5 | 6 | namespace Novacode 7 | { 8 | /// 9 | /// All DocX types are derived from DocXElement. 10 | /// This class contains properties which every element of a DocX must contain. 11 | /// 12 | public abstract class DocXElement 13 | { 14 | internal PackagePart mainPart; 15 | public PackagePart PackagePart { get { return mainPart; } set { mainPart = value; } } 16 | 17 | /// 18 | /// This is the actual Xml that gives this element substance. 19 | /// For example, a Paragraphs Xml might look something like the following 20 | ///

21 | /// 22 | /// Hello World! 23 | /// 24 | ///

25 | ///
26 | 27 | public XElement Xml { get; set; } 28 | /// 29 | /// This is a reference to the DocX object that this element belongs to. 30 | /// Every DocX element is connected to a document. 31 | /// 32 | internal DocX Document { get; set; } 33 | /// 34 | /// Store both the document and xml so that they can be accessed by derived types. 35 | /// 36 | /// The document that this element belongs to. 37 | /// The Xml that gives this element substance 38 | public DocXElement(DocX document, XElement xml) 39 | { 40 | this.Document = document; 41 | this.Xml = xml; 42 | } 43 | } 44 | 45 | /// 46 | /// This class provides functions for inserting new DocXElements before or after the current DocXElement. 47 | /// Only certain DocXElements can support these functions without creating invalid documents, at the moment these are Paragraphs and Table. 48 | /// 49 | public abstract class InsertBeforeOrAfter : DocXElement 50 | { 51 | public InsertBeforeOrAfter(DocX document, XElement xml) : base(document, xml) { } 52 | 53 | public virtual void InsertPageBreakBeforeSelf() 54 | { 55 | XElement p = new XElement 56 | ( 57 | XName.Get("p", DocX.w.NamespaceName), 58 | new XElement 59 | ( 60 | XName.Get("r", DocX.w.NamespaceName), 61 | new XElement 62 | ( 63 | XName.Get("br", DocX.w.NamespaceName), 64 | new XAttribute(XName.Get("type", DocX.w.NamespaceName), "page") 65 | ) 66 | ) 67 | ); 68 | 69 | Xml.AddBeforeSelf(p); 70 | } 71 | 72 | public virtual void InsertPageBreakAfterSelf() 73 | { 74 | XElement p = new XElement 75 | ( 76 | XName.Get("p", DocX.w.NamespaceName), 77 | new XElement 78 | ( 79 | XName.Get("r", DocX.w.NamespaceName), 80 | new XElement 81 | ( 82 | XName.Get("br", DocX.w.NamespaceName), 83 | new XAttribute(XName.Get("type", DocX.w.NamespaceName), "page") 84 | ) 85 | ) 86 | ); 87 | 88 | Xml.AddAfterSelf(p); 89 | } 90 | 91 | public virtual Paragraph InsertParagraphBeforeSelf(Paragraph p) 92 | { 93 | Xml.AddBeforeSelf(p.Xml); 94 | XElement newlyInserted = Xml.ElementsBeforeSelf().First(); 95 | 96 | p.Xml = newlyInserted; 97 | 98 | return p; 99 | } 100 | 101 | public virtual Paragraph InsertParagraphAfterSelf(Paragraph p) 102 | { 103 | Xml.AddAfterSelf(p.Xml); 104 | XElement newlyInserted = Xml.ElementsAfterSelf().First(); 105 | 106 | //Dmitchern 107 | if (this as Paragraph != null) 108 | { 109 | return new Paragraph(Document, newlyInserted, (this as Paragraph).endIndex); 110 | } 111 | 112 | p.Xml = newlyInserted; //IMPORTANT: I think we have return new paragraph in any case, but I dont know what to put as startIndex parameter into Paragraph constructor 113 | return p; 114 | } 115 | 116 | public virtual Paragraph InsertParagraphBeforeSelf(string text) 117 | { 118 | return InsertParagraphBeforeSelf(text, false, new Formatting()); 119 | } 120 | 121 | public virtual Paragraph InsertParagraphAfterSelf(string text) 122 | { 123 | return InsertParagraphAfterSelf(text, false, new Formatting()); 124 | } 125 | 126 | public virtual Paragraph InsertParagraphBeforeSelf(string text, bool trackChanges) 127 | { 128 | return InsertParagraphBeforeSelf(text, trackChanges, new Formatting()); 129 | } 130 | 131 | public virtual Paragraph InsertParagraphAfterSelf(string text, bool trackChanges) 132 | { 133 | return InsertParagraphAfterSelf(text, trackChanges, new Formatting()); 134 | } 135 | 136 | public virtual Paragraph InsertParagraphBeforeSelf(string text, bool trackChanges, Formatting formatting) 137 | { 138 | XElement newParagraph = new XElement 139 | ( 140 | XName.Get("p", DocX.w.NamespaceName), new XElement(XName.Get("pPr", DocX.w.NamespaceName)), HelperFunctions.FormatInput(text, formatting.Xml) 141 | ); 142 | 143 | if (trackChanges) 144 | newParagraph = Paragraph.CreateEdit(EditType.ins, DateTime.Now, newParagraph); 145 | 146 | Xml.AddBeforeSelf(newParagraph); 147 | XElement newlyInserted = Xml.ElementsBeforeSelf().Last(); 148 | 149 | return new Paragraph(Document, newlyInserted, -1); 150 | } 151 | 152 | public virtual Paragraph InsertParagraphAfterSelf(string text, bool trackChanges, Formatting formatting) 153 | { 154 | XElement newParagraph = new XElement 155 | ( 156 | XName.Get("p", DocX.w.NamespaceName), new XElement(XName.Get("pPr", DocX.w.NamespaceName)), HelperFunctions.FormatInput(text, formatting.Xml) 157 | ); 158 | 159 | if (trackChanges) 160 | newParagraph = Paragraph.CreateEdit(EditType.ins, DateTime.Now, newParagraph); 161 | 162 | Xml.AddAfterSelf(newParagraph); 163 | XElement newlyInserted = Xml.ElementsAfterSelf().First(); 164 | 165 | Paragraph p = new Paragraph(Document, newlyInserted, -1); 166 | 167 | return p; 168 | } 169 | 170 | public virtual Table InsertTableAfterSelf(int rowCount, int columnCount) 171 | { 172 | XElement newTable = HelperFunctions.CreateTable(rowCount, columnCount); 173 | Xml.AddAfterSelf(newTable); 174 | XElement newlyInserted = Xml.ElementsAfterSelf().First(); 175 | 176 | return new Table(Document, newlyInserted) { mainPart = mainPart }; 177 | } 178 | 179 | public virtual Table InsertTableAfterSelf(Table t) 180 | { 181 | Xml.AddAfterSelf(t.Xml); 182 | XElement newlyInserted = Xml.ElementsAfterSelf().First(); 183 | //Dmitchern 184 | return new Table(Document, newlyInserted) { mainPart = mainPart }; //return new table, dont affect parameter table 185 | } 186 | 187 | public virtual Table InsertTableBeforeSelf(int rowCount, int columnCount) 188 | { 189 | XElement newTable = HelperFunctions.CreateTable(rowCount, columnCount); 190 | Xml.AddBeforeSelf(newTable); 191 | XElement newlyInserted = Xml.ElementsBeforeSelf().Last(); 192 | 193 | return new Table(Document, newlyInserted) { mainPart = mainPart }; 194 | } 195 | 196 | public virtual Table InsertTableBeforeSelf(Table t) 197 | { 198 | Xml.AddBeforeSelf(t.Xml); 199 | XElement newlyInserted = Xml.ElementsBeforeSelf().Last(); 200 | 201 | //Dmitchern 202 | return new Table(Document, newlyInserted) { mainPart=mainPart}; //return new table, dont affect parameter table 203 | } 204 | } 205 | 206 | public static class XmlTemplateBases 207 | { 208 | #region TocXml 209 | public const string TocXmlBase = @" 210 | 211 | 212 | 213 | 214 | \ 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | {1} 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | {3} 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | "; 267 | public const string TocHeadingStyleBase = @" 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | "; 284 | public const string TocElementStyleBase = @" 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | "; 297 | public const string TocHyperLinkStyleBase = @" 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | "; 308 | #endregion 309 | } 310 | } 311 | -------------------------------------------------------------------------------- /src/DocXCore/_Enumerations.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | 4 | namespace Novacode 5 | { 6 | 7 | public enum ListItemType 8 | { 9 | Bulleted, 10 | Numbered 11 | } 12 | 13 | public enum SectionBreakType 14 | { 15 | defaultNextPage, 16 | evenPage, 17 | oddPage, 18 | continuous 19 | } 20 | 21 | 22 | public enum ContainerType 23 | { 24 | None, 25 | TOC, 26 | Section, 27 | Cell, 28 | Table, 29 | Header, 30 | Footer, 31 | Paragraph, 32 | Body 33 | } 34 | 35 | public enum PageNumberFormat 36 | { 37 | normal, 38 | roman 39 | } 40 | 41 | public enum BorderSize 42 | { 43 | one, 44 | two, 45 | three, 46 | four, 47 | five, 48 | six, 49 | seven, 50 | eight, 51 | nine 52 | } 53 | 54 | public enum EditRestrictions 55 | { 56 | none, 57 | readOnly, 58 | forms, 59 | comments, 60 | trackedChanges 61 | } 62 | 63 | /// 64 | /// Table Cell Border styles 65 | /// Added by lckuiper @ 20101117 66 | /// source: http://msdn.microsoft.com/en-us/library/documentformat.openxml.wordprocessing.tablecellborders.aspx 67 | /// 68 | public enum BorderStyle 69 | { 70 | Tcbs_none = 0, 71 | Tcbs_single, 72 | Tcbs_thick, 73 | Tcbs_double, 74 | Tcbs_dotted, 75 | Tcbs_dashed, 76 | Tcbs_dotDash, 77 | Tcbs_dotDotDash, 78 | Tcbs_triple, 79 | Tcbs_thinThickSmallGap, 80 | Tcbs_thickThinSmallGap, 81 | Tcbs_thinThickThinSmallGap, 82 | Tcbs_thinThickMediumGap, 83 | Tcbs_thickThinMediumGap, 84 | Tcbs_thinThickThinMediumGap, 85 | Tcbs_thinThickLargeGap, 86 | Tcbs_thickThinLargeGap, 87 | Tcbs_thinThickThinLargeGap, 88 | Tcbs_wave, 89 | Tcbs_doubleWave, 90 | Tcbs_dashSmallGap, 91 | Tcbs_dashDotStroked, 92 | Tcbs_threeDEmboss, 93 | Tcbs_threeDEngrave, 94 | Tcbs_outset, 95 | Tcbs_inset, 96 | Tcbs_nil 97 | } 98 | 99 | /// 100 | /// Table Cell Border Types 101 | /// Added by lckuiper @ 20101117 102 | /// source: http://msdn.microsoft.com/en-us/library/documentformat.openxml.wordprocessing.tablecellborders.aspx 103 | /// 104 | public enum TableCellBorderType 105 | { 106 | Top, 107 | Bottom, 108 | Left, 109 | Right, 110 | InsideH, 111 | InsideV, 112 | TopLeftToBottomRight, 113 | TopRightToBottomLeft 114 | } 115 | 116 | /// 117 | /// Table Border Types 118 | /// Added by lckuiper @ 20101117 119 | /// source: http://msdn.microsoft.com/en-us/library/documentformat.openxml.wordprocessing.tableborders.aspx 120 | /// 121 | public enum TableBorderType 122 | { 123 | Top, 124 | Bottom, 125 | Left, 126 | Right, 127 | InsideH, 128 | InsideV 129 | } 130 | 131 | // Patch 7398 added by lckuiper on Nov 16th 2010 @ 2:23 PM 132 | public enum VerticalAlignment 133 | { 134 | Top, 135 | Center, 136 | Bottom 137 | }; 138 | 139 | public enum Orientation 140 | { 141 | Portrait, 142 | Landscape 143 | }; 144 | 145 | public enum XmlDocument 146 | { 147 | Main, 148 | HeaderOdd, 149 | HeaderEven, 150 | HeaderFirst, 151 | FooterOdd, 152 | FooterEven, 153 | FooterFirst 154 | }; 155 | 156 | public enum MatchFormattingOptions 157 | { 158 | ExactMatch, 159 | SubsetMatch 160 | }; 161 | 162 | public enum Script 163 | { 164 | superscript, 165 | subscript, 166 | none 167 | } 168 | 169 | public enum Highlight 170 | { 171 | yellow, 172 | green, 173 | cyan, 174 | magenta, 175 | blue, 176 | red, 177 | darkBlue, 178 | darkCyan, 179 | darkGreen, 180 | darkMagenta, 181 | darkRed, 182 | darkYellow, 183 | darkGray, 184 | lightGray, 185 | black, 186 | none 187 | }; 188 | 189 | public enum UnderlineStyle 190 | { 191 | none = 0, 192 | singleLine = 1, 193 | words = 2, 194 | doubleLine = 3, 195 | dotted = 4, 196 | thick = 6, 197 | dash = 7, 198 | dotDash = 9, 199 | dotDotDash = 10, 200 | wave = 11, 201 | dottedHeavy = 20, 202 | dashedHeavy = 23, 203 | dashDotHeavy = 25, 204 | dashDotDotHeavy = 26, 205 | dashLongHeavy = 27, 206 | dashLong = 39, 207 | wavyDouble = 43, 208 | wavyHeavy = 55, 209 | }; 210 | 211 | public enum StrikeThrough 212 | { 213 | none, 214 | strike, 215 | doubleStrike 216 | }; 217 | 218 | public enum Misc 219 | { 220 | none, 221 | shadow, 222 | outline, 223 | outlineShadow, 224 | emboss, 225 | engrave 226 | }; 227 | 228 | /// 229 | /// Change the caps style of text, for use with Append and AppendLine. 230 | /// 231 | public enum CapsStyle 232 | { 233 | /// 234 | /// No caps, make all characters are lowercase. 235 | /// 236 | none, 237 | 238 | /// 239 | /// All caps, make every character uppercase. 240 | /// 241 | caps, 242 | 243 | /// 244 | /// Small caps, make all characters capital but with a small font size. 245 | /// 246 | smallCaps 247 | }; 248 | 249 | /// 250 | /// Designs\Styles that can be applied to a table. 251 | /// 252 | public enum TableDesign 253 | { 254 | Custom, 255 | TableNormal, 256 | TableGrid, 257 | LightShading, 258 | LightShadingAccent1, 259 | LightShadingAccent2, 260 | LightShadingAccent3, 261 | LightShadingAccent4, 262 | LightShadingAccent5, 263 | LightShadingAccent6, 264 | LightList, 265 | LightListAccent1, 266 | LightListAccent2, 267 | LightListAccent3, 268 | LightListAccent4, 269 | LightListAccent5, 270 | LightListAccent6, 271 | LightGrid, 272 | LightGridAccent1, 273 | LightGridAccent2, 274 | LightGridAccent3, 275 | LightGridAccent4, 276 | LightGridAccent5, 277 | LightGridAccent6, 278 | MediumShading1, 279 | MediumShading1Accent1, 280 | MediumShading1Accent2, 281 | MediumShading1Accent3, 282 | MediumShading1Accent4, 283 | MediumShading1Accent5, 284 | MediumShading1Accent6, 285 | MediumShading2, 286 | MediumShading2Accent1, 287 | MediumShading2Accent2, 288 | MediumShading2Accent3, 289 | MediumShading2Accent4, 290 | MediumShading2Accent5, 291 | MediumShading2Accent6, 292 | MediumList1, 293 | MediumList1Accent1, 294 | MediumList1Accent2, 295 | MediumList1Accent3, 296 | MediumList1Accent4, 297 | MediumList1Accent5, 298 | MediumList1Accent6, 299 | MediumList2, 300 | MediumList2Accent1, 301 | MediumList2Accent2, 302 | MediumList2Accent3, 303 | MediumList2Accent4, 304 | MediumList2Accent5, 305 | MediumList2Accent6, 306 | MediumGrid1, 307 | MediumGrid1Accent1, 308 | MediumGrid1Accent2, 309 | MediumGrid1Accent3, 310 | MediumGrid1Accent4, 311 | MediumGrid1Accent5, 312 | MediumGrid1Accent6, 313 | MediumGrid2, 314 | MediumGrid2Accent1, 315 | MediumGrid2Accent2, 316 | MediumGrid2Accent3, 317 | MediumGrid2Accent4, 318 | MediumGrid2Accent5, 319 | MediumGrid2Accent6, 320 | MediumGrid3, 321 | MediumGrid3Accent1, 322 | MediumGrid3Accent2, 323 | MediumGrid3Accent3, 324 | MediumGrid3Accent4, 325 | MediumGrid3Accent5, 326 | MediumGrid3Accent6, 327 | DarkList, 328 | DarkListAccent1, 329 | DarkListAccent2, 330 | DarkListAccent3, 331 | DarkListAccent4, 332 | DarkListAccent5, 333 | DarkListAccent6, 334 | ColorfulShading, 335 | ColorfulShadingAccent1, 336 | ColorfulShadingAccent2, 337 | ColorfulShadingAccent3, 338 | ColorfulShadingAccent4, 339 | ColorfulShadingAccent5, 340 | ColorfulShadingAccent6, 341 | ColorfulList, 342 | ColorfulListAccent1, 343 | ColorfulListAccent2, 344 | ColorfulListAccent3, 345 | ColorfulListAccent4, 346 | ColorfulListAccent5, 347 | ColorfulListAccent6, 348 | ColorfulGrid, 349 | ColorfulGridAccent1, 350 | ColorfulGridAccent2, 351 | ColorfulGridAccent3, 352 | ColorfulGridAccent4, 353 | ColorfulGridAccent5, 354 | ColorfulGridAccent6, 355 | None 356 | }; 357 | 358 | /// 359 | /// How a Table should auto resize. 360 | /// 361 | public enum AutoFit 362 | { 363 | /// 364 | /// Autofit to Table contents. 365 | /// 366 | Contents, 367 | 368 | /// 369 | /// Autofit to Window. 370 | /// 371 | Window, 372 | 373 | /// 374 | /// Autofit to Column width. 375 | /// 376 | ColumnWidth, 377 | /// 378 | /// Autofit to Fixed column width 379 | /// 380 | Fixed 381 | }; 382 | 383 | public enum RectangleShapes 384 | { 385 | rect, 386 | roundRect, 387 | snip1Rect, 388 | snip2SameRect, 389 | snip2DiagRect, 390 | snipRoundRect, 391 | round1Rect, 392 | round2SameRect, 393 | round2DiagRect 394 | }; 395 | 396 | public enum BasicShapes 397 | { 398 | ellipse, 399 | triangle, 400 | rtTriangle, 401 | parallelogram, 402 | trapezoid, 403 | diamond, 404 | pentagon, 405 | hexagon, 406 | heptagon, 407 | octagon, 408 | decagon, 409 | dodecagon, 410 | pie, 411 | chord, 412 | teardrop, 413 | frame, 414 | halfFrame, 415 | corner, 416 | diagStripe, 417 | plus, 418 | plaque, 419 | can, 420 | cube, 421 | bevel, 422 | donut, 423 | noSmoking, 424 | blockArc, 425 | foldedCorner, 426 | smileyFace, 427 | heart, 428 | lightningBolt, 429 | sun, 430 | moon, 431 | cloud, 432 | arc, 433 | backetPair, 434 | bracePair, 435 | leftBracket, 436 | rightBracket, 437 | leftBrace, 438 | rightBrace 439 | }; 440 | 441 | public enum BlockArrowShapes 442 | { 443 | rightArrow, 444 | leftArrow, 445 | upArrow, 446 | downArrow, 447 | leftRightArrow, 448 | upDownArrow, 449 | quadArrow, 450 | leftRightUpArrow, 451 | bentArrow, 452 | uturnArrow, 453 | leftUpArrow, 454 | bentUpArrow, 455 | curvedRightArrow, 456 | curvedLeftArrow, 457 | curvedUpArrow, 458 | curvedDownArrow, 459 | stripedRightArrow, 460 | notchedRightArrow, 461 | homePlate, 462 | chevron, 463 | rightArrowCallout, 464 | downArrowCallout, 465 | leftArrowCallout, 466 | upArrowCallout, 467 | leftRightArrowCallout, 468 | quadArrowCallout, 469 | circularArrow 470 | }; 471 | 472 | public enum EquationShapes 473 | { 474 | mathPlus, 475 | mathMinus, 476 | mathMultiply, 477 | mathDivide, 478 | mathEqual, 479 | mathNotEqual 480 | }; 481 | 482 | public enum FlowchartShapes 483 | { 484 | flowChartProcess, 485 | flowChartAlternateProcess, 486 | flowChartDecision, 487 | flowChartInputOutput, 488 | flowChartPredefinedProcess, 489 | flowChartInternalStorage, 490 | flowChartDocument, 491 | flowChartMultidocument, 492 | flowChartTerminator, 493 | flowChartPreparation, 494 | flowChartManualInput, 495 | flowChartManualOperation, 496 | flowChartConnector, 497 | flowChartOffpageConnector, 498 | flowChartPunchedCard, 499 | flowChartPunchedTape, 500 | flowChartSummingJunction, 501 | flowChartOr, 502 | flowChartCollate, 503 | flowChartSort, 504 | flowChartExtract, 505 | flowChartMerge, 506 | flowChartOnlineStorage, 507 | flowChartDelay, 508 | flowChartMagneticTape, 509 | flowChartMagneticDisk, 510 | flowChartMagneticDrum, 511 | flowChartDisplay 512 | }; 513 | 514 | public enum StarAndBannerShapes 515 | { 516 | irregularSeal1, 517 | irregularSeal2, 518 | star4, 519 | star5, 520 | star6, 521 | star7, 522 | star8, 523 | star10, 524 | star12, 525 | star16, 526 | star24, 527 | star32, 528 | ribbon, 529 | ribbon2, 530 | ellipseRibbon, 531 | ellipseRibbon2, 532 | verticalScroll, 533 | horizontalScroll, 534 | wave, 535 | doubleWave 536 | }; 537 | 538 | public enum CalloutShapes 539 | { 540 | wedgeRectCallout, 541 | wedgeRoundRectCallout, 542 | wedgeEllipseCallout, 543 | cloudCallout, 544 | borderCallout1, 545 | borderCallout2, 546 | borderCallout3, 547 | accentCallout1, 548 | accentCallout2, 549 | accentCallout3, 550 | callout1, 551 | callout2, 552 | callout3, 553 | accentBorderCallout1, 554 | accentBorderCallout2, 555 | accentBorderCallout3 556 | }; 557 | 558 | /// 559 | /// Text alignment of a Paragraph. 560 | /// 561 | public enum Alignment 562 | { 563 | /// 564 | /// Align Paragraph to the left. 565 | /// 566 | left, 567 | 568 | /// 569 | /// Align Paragraph as centered. 570 | /// 571 | center, 572 | 573 | /// 574 | /// Align Paragraph to the right. 575 | /// 576 | right, 577 | 578 | /// 579 | /// (Justified) Align Paragraph to both the left and right margins, adding extra space between content as necessary. 580 | /// 581 | both 582 | }; 583 | 584 | public enum Direction 585 | { 586 | LeftToRight, 587 | RightToLeft 588 | }; 589 | 590 | /// 591 | /// Paragraph edit types 592 | /// 593 | internal enum EditType 594 | { 595 | /// 596 | /// A ins is a tracked insertion 597 | /// 598 | ins, 599 | 600 | /// 601 | /// A del is tracked deletion 602 | /// 603 | del 604 | } 605 | 606 | /// 607 | /// Custom property types. 608 | /// 609 | internal enum CustomPropertyType 610 | { 611 | /// 612 | /// System.String 613 | /// 614 | Text, 615 | 616 | /// 617 | /// System.DateTime 618 | /// 619 | Date, 620 | 621 | /// 622 | /// System.Int32 623 | /// 624 | NumberInteger, 625 | 626 | /// 627 | /// System.Double 628 | /// 629 | NumberDecimal, 630 | 631 | /// 632 | /// System.Boolean 633 | /// 634 | YesOrNo 635 | } 636 | 637 | /// 638 | /// Text types in a Run 639 | /// 640 | public enum RunTextType 641 | { 642 | /// 643 | /// System.String 644 | /// 645 | Text, 646 | 647 | /// 648 | /// System.String 649 | /// 650 | DelText, 651 | } 652 | public enum LineSpacingType 653 | { 654 | Line, 655 | Before, 656 | After 657 | } 658 | 659 | public enum LineSpacingTypeAuto 660 | { 661 | AutoBefore, 662 | AutoAfter, 663 | Auto, 664 | None 665 | } 666 | 667 | /// 668 | /// Cell margin for all sides of the table cell. 669 | /// 670 | public enum TableCellMarginType 671 | { 672 | /// 673 | /// The left cell margin. 674 | /// 675 | left, 676 | /// 677 | /// The right cell margin. 678 | /// 679 | right, 680 | /// 681 | /// The bottom cell margin. 682 | /// 683 | bottom, 684 | /// 685 | /// The top cell margin. 686 | /// 687 | top 688 | } 689 | 690 | public enum HeadingType 691 | { 692 | [Description("Heading1")] 693 | Heading1, 694 | 695 | [Description("Heading2")] 696 | Heading2, 697 | 698 | [Description("Heading3")] 699 | Heading3, 700 | 701 | [Description("Heading4")] 702 | Heading4, 703 | 704 | [Description("Heading5")] 705 | Heading5, 706 | 707 | [Description("Heading6")] 708 | Heading6, 709 | 710 | [Description("Heading7")] 711 | Heading7, 712 | 713 | [Description("Heading8")] 714 | Heading8, 715 | 716 | [Description("Heading9")] 717 | Heading9, 718 | 719 | 720 | /* 721 | * The Character Based Headings below do not work in the same way as the headings 1-9 above, but appear on the same list in word. 722 | * I have kept them here for reference in case somebody else things its just a matter of adding them in to gain extra headings 723 | */ 724 | #region Other character (NOT paragraph) based Headings 725 | //[Description("NoSpacing")] 726 | //NoSpacing, 727 | 728 | //[Description("Title")] 729 | //Title, 730 | 731 | //[Description("Subtitle")] 732 | //Subtitle, 733 | 734 | //[Description("Quote")] 735 | //Quote, 736 | 737 | //[Description("IntenseQuote")] 738 | //IntenseQuote, 739 | 740 | //[Description("Emphasis")] 741 | //Emphasis, 742 | 743 | //[Description("IntenseEmphasis")] 744 | //IntenseEmphasis, 745 | 746 | //[Description("Strong")] 747 | //Strong, 748 | 749 | //[Description("ListParagraph")] 750 | //ListParagraph, 751 | 752 | //[Description("SubtleReference")] 753 | //SubtleReference, 754 | 755 | //[Description("IntenseReference")] 756 | //IntenseReference, 757 | 758 | //[Description("BookTitle")] 759 | //BookTitle, 760 | #endregion 761 | 762 | 763 | } 764 | public enum TextDirection 765 | { 766 | btLr, 767 | right 768 | }; 769 | 770 | /// 771 | /// Represents the switches set on a TOC. 772 | /// 773 | [Flags] 774 | public enum TableOfContentsSwitches 775 | { 776 | None = 0 << 0, 777 | [Description("\\a")] 778 | A = 1 << 0, 779 | [Description("\\b")] 780 | B = 1 << 1, 781 | [Description("\\c")] 782 | C = 1 << 2, 783 | [Description("\\d")] 784 | D = 1 << 3, 785 | [Description("\\f")] 786 | F = 1 << 4, 787 | [Description("\\h")] 788 | H = 1 << 5, 789 | [Description("\\l")] 790 | L = 1 << 6, 791 | [Description("\\n")] 792 | N = 1 << 7, 793 | [Description("\\o")] 794 | O = 1 << 8, 795 | [Description("\\p")] 796 | P = 1 << 9, 797 | [Description("\\s")] 798 | S = 1 << 10, 799 | [Description("\\t")] 800 | T = 1 << 11, 801 | [Description("\\u")] 802 | U = 1 << 12, 803 | [Description("\\w")] 804 | W = 1 << 13, 805 | [Description("\\x")] 806 | X = 1 << 14, 807 | [Description("\\z")] 808 | Z = 1 << 15, 809 | } 810 | 811 | } -------------------------------------------------------------------------------- /src/DocXCore/_Extensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Drawing; 4 | using System.Xml.Linq; 5 | 6 | namespace Novacode 7 | { 8 | internal static class Extensions 9 | { 10 | internal static string ToHex(this Color source) 11 | { 12 | byte red = source.R; 13 | byte green = source.G; 14 | byte blue = source.B; 15 | 16 | string redHex = red.ToString("X"); 17 | if (redHex.Length < 2) 18 | redHex = "0" + redHex; 19 | 20 | string blueHex = blue.ToString("X"); 21 | if (blueHex.Length < 2) 22 | blueHex = "0" + blueHex; 23 | 24 | string greenHex = green.ToString("X"); 25 | if (greenHex.Length < 2) 26 | greenHex = "0" + greenHex; 27 | 28 | return string.Format("{0}{1}{2}", redHex, greenHex, blueHex); 29 | } 30 | 31 | public static void Flatten(this XElement e, XName name, List flat) 32 | { 33 | // Add this element (without its children) to the flat list. 34 | XElement clone = CloneElement(e); 35 | clone.Elements().Remove(); 36 | 37 | // Filter elements using XName. 38 | if (clone.Name == name) 39 | flat.Add(clone); 40 | 41 | // Process the children. 42 | if (e.HasElements) 43 | foreach (XElement elem in e.Elements(name)) // Filter elements using XName 44 | elem.Flatten(name, flat); 45 | } 46 | 47 | static XElement CloneElement(XElement element) 48 | { 49 | return new XElement(element.Name, 50 | element.Attributes(), 51 | element.Nodes().Select(n => 52 | { 53 | XElement e = n as XElement; 54 | if (e != null) 55 | return CloneElement(e); 56 | return n; 57 | } 58 | ) 59 | ); 60 | } 61 | 62 | public static string GetAttribute(this XElement el, XName name, string defaultValue = "") 63 | { 64 | var attr = el.Attribute(name); 65 | if (attr != null) 66 | return attr.Value; 67 | return defaultValue; 68 | } 69 | 70 | /// 71 | /// Sets margin for all the pages in a Dox document in Inches. (Written by Shashwat Tripathi) 72 | /// 73 | /// 74 | /// Margin from the Top. Leave -1 for no change 75 | /// Margin from the Bottom. Leave -1 for no change 76 | /// Margin from the Right. Leave -1 for no change 77 | /// Margin from the Left. Leave -1 for no change 78 | public static void SetMargin(this DocX document, float top, float bottom, float right, float left) 79 | { 80 | XNamespace ab = "http://schemas.openxmlformats.org/wordprocessingml/2006/main"; 81 | var tempElement = document.PageLayout.Xml.Descendants(ab + "pgMar"); 82 | 83 | foreach (var item in tempElement) 84 | { 85 | if (left != -1) 86 | item.SetAttributeValue(ab + "left", (1440 * left) / 1); 87 | if (right != -1) 88 | item.SetAttributeValue(ab + "right", (1440 * right) / 1); 89 | if (top != -1) 90 | item.SetAttributeValue(ab + "top", (1440 * top) / 1); 91 | if (bottom != -1) 92 | item.SetAttributeValue(ab + "bottom", (1440 * bottom) / 1); 93 | } 94 | } 95 | } 96 | 97 | } 98 | --------------------------------------------------------------------------------