| c.AddSeries( s1 ); | c.AddSeries( s1 ); | ||||
| // Insert chart into document | // Insert chart into document | ||||
| document.InsertParagraph( "Expenses(M$) for selected categories of Canada" ).FontSize( 15 ).SpacingAfter( 10d ); | |||||
| document.InsertParagraph( "Expenses(M$) for selected categories in Canada" ).FontSize( 15 ).SpacingAfter( 10d ); | |||||
| document.InsertChart( c ); | document.InsertChart( c ); | ||||
| document.Save(); | document.Save(); | ||||
| c.AddSeries( s1 ); | c.AddSeries( s1 ); | ||||
| // Insert chart into document | // Insert chart into document | ||||
| document.InsertParagraph( "Expenses(M$) for selected categories of Brazil" ).FontSize( 15 ).SpacingAfter( 10d ); | |||||
| document.InsertParagraph( "Expenses(M$) for selected categories in Brazil" ).FontSize( 15 ).SpacingAfter( 10d ); | |||||
| document.InsertChart( c ); | document.InsertChart( c ); | ||||
| document.Save(); | document.Save(); |
| p2.AppendHyperlink( h2 ).Color( Color.Blue ).UnderlineStyle( UnderlineStyle.singleLine ); | p2.AppendHyperlink( h2 ).Color( Color.Blue ).UnderlineStyle( UnderlineStyle.singleLine ); | ||||
| p2.Append( "." ).SpacingAfter( 40d ); | p2.Append( "." ).SpacingAfter( 40d ); | ||||
| // Create a bookmark anchor. | |||||
| var bookmarkAnchor = "bookmarkAnchor"; | |||||
| // Add an Hyperlink to this document pointing to a bookmark anchor. | |||||
| var h3 = document.AddHyperlink( "Special Data", bookmarkAnchor ); | |||||
| // Add a paragraph. | |||||
| var p3 = document.InsertParagraph( "An hyperlink pointing to a bookmark of this Document has been added at the end of this paragraph: " ); | |||||
| // Append an hyperlink to a paragraph. | |||||
| p3.AppendHyperlink( h3 ).Color( Color.Red ).UnderlineStyle( UnderlineStyle.singleLine ); | |||||
| p3.Append( "." ).SpacingAfter( 40d ); | |||||
| // Add an Hyperlink to this document. | // Add an Hyperlink to this document. | ||||
| var h3 = document.AddHyperlink( "microsoft", new Uri( "http://www.microsoft.com" ) ); | |||||
| var h4 = document.AddHyperlink( "microsoft", new Uri( "http://www.microsoft.com" ) ); | |||||
| // Add a paragraph | // Add a paragraph | ||||
| var p3 = document.InsertParagraph( "The hyperlink from this paragraph has been removed. " ); | |||||
| var p4 = document.InsertParagraph( "The hyperlink from this paragraph has been removed. " ); | |||||
| // Append an hyperlink to a paragraph. | // Append an hyperlink to a paragraph. | ||||
| p3.AppendHyperlink( h3 ).Color( Color.Green ).UnderlineStyle( UnderlineStyle.singleLine ).Italic(); | |||||
| p4.AppendHyperlink( h4 ).Color( Color.Green ).UnderlineStyle( UnderlineStyle.singleLine ).Italic(); | |||||
| // Remove the first hyperlink of paragraph 3. | |||||
| p3.RemoveHyperlink( 0 ); | |||||
| // Remove the first hyperlink of paragraph 4. | |||||
| p4.RemoveHyperlink( 0 ); | |||||
| // Add a paragraph. | |||||
| var p5 = document.InsertParagraph( "This is a paragraph containing a" ); | |||||
| // Add a bookmark into the paragraph by setting its bookmark anchor. | |||||
| p5.AppendBookmark( bookmarkAnchor ); | |||||
| p5.Append( " bookmark " ); | |||||
| p5.Append( "referenced by a hyperlink defined in an earlier paragraph." ); | |||||
| p5.SpacingBefore( 200d ); | |||||
| document.Save(); | document.Save(); | ||||
| Console.WriteLine( "\tCreated: Hyperlinks.docx\n" ); | Console.WriteLine( "\tCreated: Hyperlinks.docx\n" ); |
| using( var document = DocX.Create( LineSample.LineSampleOutputDirectory + @"InsertHorizontalLine.docx" ) ) | using( var document = DocX.Create( LineSample.LineSampleOutputDirectory + @"InsertHorizontalLine.docx" ) ) | ||||
| { | { | ||||
| // Add a title | // Add a title | ||||
| document.InsertParagraph( "Adding bottom Horizontal lines" ).FontSize( 15d ).SpacingAfter( 50d ).Alignment = Alignment.center; | |||||
| document.InsertParagraph( "Adding top or bottom Horizontal lines" ).FontSize( 15d ).SpacingAfter( 50d ).Alignment = Alignment.center; | |||||
| // Add a paragraph with a single line. | // Add a paragraph with a single line. | ||||
| var p = document.InsertParagraph(); | var p = document.InsertParagraph(); | ||||
| p.Append( "This is a paragraph with a single line." ).Font( new Font( "Arial" ) ).FontSize( 20 ); | |||||
| p.InsertHorizontalLine( "single", 6, 1, "auto" ); | |||||
| p.Append( "This is a paragraph with a single bottom line." ).Font( new Font( "Arial" ) ).FontSize( 15 ); | |||||
| p.InsertHorizontalLine( HorizontalBorderPosition.bottom, "single", 6, 1, "auto" ); | |||||
| p.SpacingAfter( 20 ); | p.SpacingAfter( 20 ); | ||||
| // Add a paragraph with a double green line. | // Add a paragraph with a double green line. | ||||
| var p2 = document.InsertParagraph(); | var p2 = document.InsertParagraph(); | ||||
| p2.Append( "This is a paragraph with a double colored line." ).Font( new Font( "Arial" ) ).FontSize( 20 ); | |||||
| p2.InsertHorizontalLine( "double", 6, 1, "green" ); | |||||
| p2.Append( "This is a paragraph with a double bottom colored line." ).Font( new Font( "Arial" ) ).FontSize( 15 ); | |||||
| p2.InsertHorizontalLine( HorizontalBorderPosition.bottom, "double", 6, 1, "green" ); | |||||
| p2.SpacingAfter( 20 ); | p2.SpacingAfter( 20 ); | ||||
| // Add a paragraph with a triple red line. | // Add a paragraph with a triple red line. | ||||
| var p3 = document.InsertParagraph(); | var p3 = document.InsertParagraph(); | ||||
| p3.Append( "This is a paragraph with a triple colored line." ).Font( new Font( "Arial" ) ).FontSize( 20 ); | |||||
| p3.InsertHorizontalLine( "triple", 6, 1, "red" ); | |||||
| p3.Append( "This is a paragraph with a triple bottom colored line." ).Font( new Font( "Arial" ) ).FontSize( 15 ); | |||||
| p3.InsertHorizontalLine( HorizontalBorderPosition.bottom, "triple", 6, 1, "red" ); | |||||
| p3.SpacingAfter( 20 ); | p3.SpacingAfter( 20 ); | ||||
| // Add a paragraph with a single spaced line. | // Add a paragraph with a single spaced line. | ||||
| var p4 = document.InsertParagraph(); | var p4 = document.InsertParagraph(); | ||||
| p4.Append( "This is a paragraph with a spaced line." ).Font( new Font( "Arial" ) ).FontSize( 20 ); | |||||
| p4.InsertHorizontalLine( "single", 6, 12, "auto" ); | |||||
| p4.Append( "This is a paragraph with a spaced bottom line." ).Font( new Font( "Arial" ) ).FontSize( 15 ); | |||||
| p4.InsertHorizontalLine( HorizontalBorderPosition.bottom, "single", 6, 12, "auto" ); | |||||
| p4.SpacingAfter( 20 ); | p4.SpacingAfter( 20 ); | ||||
| // Add a paragraph with a single large line. | // Add a paragraph with a single large line. | ||||
| var p5 = document.InsertParagraph(); | var p5 = document.InsertParagraph(); | ||||
| p5.Append( "This is a paragraph with a large line." ).Font( new Font( "Arial" ) ).FontSize( 20 ); | |||||
| p5.InsertHorizontalLine( "single", 25, 1, "auto" ); | |||||
| p5.Append( "This is a paragraph with a large bottom line." ).Font( new Font( "Arial" ) ).FontSize( 15 ); | |||||
| p5.InsertHorizontalLine( HorizontalBorderPosition.bottom, "single", 25, 1, "auto" ); | |||||
| p5.SpacingAfter( 60 ); | |||||
| // Add a paragraph with a single blue top line. | |||||
| var p6 = document.InsertParagraph(); | |||||
| p6.Append( "This is a paragraph with a blue top line." ).Font( new Font( "Arial" ) ).FontSize( 15 ); | |||||
| p6.InsertHorizontalLine( HorizontalBorderPosition.top, "single", 6, 1, "blue" ); | |||||
| p5.SpacingAfter( 20 ); | p5.SpacingAfter( 20 ); | ||||
| document.Save(); | document.Save(); |
| .Italic() | .Italic() | ||||
| .Spacing( 5 ) | .Spacing( 5 ) | ||||
| .Append( "highlight" ).Highlight( Highlight.yellow ).UnderlineColor( Color.Blue ).CapsStyle( CapsStyle.caps ) | .Append( "highlight" ).Highlight( Highlight.yellow ).UnderlineColor( Color.Blue ).CapsStyle( CapsStyle.caps ) | ||||
| .Append( " and strike through." ).StrikeThrough( StrikeThrough.strike ); | |||||
| .Append( " and strike through." ).StrikeThrough( StrikeThrough.strike ) | |||||
| .SpacingAfter( 40 ); | |||||
| // Insert another Paragraph into this document. | |||||
| var p3 = document.InsertParagraph(); | |||||
| // Append some text with 2 TabStopPositions. | |||||
| p3.InsertTabStopPosition( Alignment.center, 216f, TabStopPositionLeader.dot ) | |||||
| .InsertTabStopPosition( Alignment.right, 432f, TabStopPositionLeader.dot ) | |||||
| .Append( "Text with TabStopPositions on Left\tMiddle\tand Right" ) | |||||
| .SpacingAfter( 40 ); | |||||
| // Save this document to disk. | // Save this document to disk. | ||||
| document.Save(); | document.Save(); | ||||
| // Replace "<COST>" with "$13.95" using an handler | // Replace "<COST>" with "$13.95" using an handler | ||||
| p4.ReplaceText( "<(.*?)>", ReplaceTextHandler, false, RegexOptions.IgnoreCase, null, new Formatting() ); | p4.ReplaceText( "<(.*?)>", ReplaceTextHandler, false, RegexOptions.IgnoreCase, null, new Formatting() ); | ||||
| p4.SpacingAfter( 30 ); | |||||
| // Insert another Paragraph into this document. | |||||
| var p5 = document.InsertParagraph(); | |||||
| // Append some text with track changes | |||||
| p5.Append( "This is a paragraph where tracking of modifications is used." ); | |||||
| p5.ReplaceText( "modifications", "changes", true ); | |||||
| // Save this document to disk. | // Save this document to disk. | ||||
| document.Save(); | document.Save(); | ||||
| Console.WriteLine( "\tCreated: TextActions.docx\n" ); | Console.WriteLine( "\tCreated: TextActions.docx\n" ); |
| document.InsertParagraph( "Columns width" ).FontSize( 15d ).SpacingAfter( 50d ).Alignment = Alignment.center; | document.InsertParagraph( "Columns width" ).FontSize( 15d ).SpacingAfter( 50d ).Alignment = Alignment.center; | ||||
| // Insert a title paragraph. | // Insert a title paragraph. | ||||
| var p = document.InsertParagraph( "In the following table, the cell's left margin has been removed for rows 2-5 as well as the top/bottom table's borders." ).Bold(); | |||||
| var p = document.InsertParagraph( "In the following table, the cell's left margin has been removed for rows 2-6 as well as the top/bottom table's borders." ).Bold(); | |||||
| p.Alignment = Alignment.center; | p.Alignment = Alignment.center; | ||||
| p.SpacingAfter( 40d ); | p.SpacingAfter( 40d ); | ||||
| <?xml version="1.0"?> | |||||
| <configuration> | |||||
| <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration> |
| <?xml version="1.0"?> | |||||
| <configuration> | |||||
| <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration> |
| <?xml version="1.0" encoding="UTF-8" standalone="yes"?> | |||||
| <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> | |||||
| <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/> | |||||
| <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> | |||||
| <security> | |||||
| <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"> | |||||
| <requestedExecutionLevel level="asInvoker" uiAccess="false"/> | |||||
| </requestedPrivileges> | |||||
| </security> | |||||
| </trustInfo> | |||||
| </assembly> |
| <?xml version="1.0"?> | |||||
| <configuration> | |||||
| <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration> |
| <?xml version="1.0"?> | |||||
| <configuration> | |||||
| <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration> |
| <?xml version="1.0" encoding="UTF-8" standalone="yes"?> | |||||
| <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> | |||||
| <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/> | |||||
| <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> | |||||
| <security> | |||||
| <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"> | |||||
| <requestedExecutionLevel level="asInvoker" uiAccess="false"/> | |||||
| </requestedPrivileges> | |||||
| </security> | |||||
| </trustInfo> | |||||
| </assembly> |
| D:\Dev\DocumentLibraries\Release\1.2.0\OpenSource\Generated\Examples\bin\Debug\Examples.exe.config |
| D:\Dev\DocumentLibraries\Release\1.2.0\OpenSource\Generated\Examples\bin\Release\Examples.exe.config | |||||
| D:\Dev\DocumentLibraries\Release\1.2.0\OpenSource\Generated\Examples\bin\Release\Examples.exe | |||||
| D:\Dev\DocumentLibraries\Release\1.2.0\OpenSource\Generated\Examples\bin\Release\Xceed.Words.NET.dll | |||||
| D:\Dev\DocumentLibraries\Release\1.2.0\OpenSource\Generated\Examples\obj\x86\Release\Xceed.Words.NET.Examples.csprojResolveAssemblyReference.cache | |||||
| D:\Dev\DocumentLibraries\Release\1.2.0\OpenSource\Generated\Examples\obj\x86\Release\Examples.exe |
| internal static class _XceedVersionInfo | internal static class _XceedVersionInfo | ||||
| { | { | ||||
| [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] | [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] | ||||
| public const string BaseVersion = "1.1"; | |||||
| public const string BaseVersion = "1.2"; | |||||
| [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] | [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] | ||||
| public const string Version = BaseVersion + | public const string Version = BaseVersion + | ||||
| ".0.0"; | ".0.0"; |
| } | } | ||||
| } | } | ||||
| XElement body = Xml.Element( XName.Get( "body", DocX.w.NamespaceName ) ); | |||||
| XElement baseSectionXml = body?.Element( XName.Get( "sectPr", DocX.w.NamespaceName ) ); | |||||
| var body = Xml.DescendantsAndSelf( XName.Get( "body", DocX.w.NamespaceName ) ).FirstOrDefault(); | |||||
| var baseSectionXml = body?.Element( XName.Get( "sectPr", DocX.w.NamespaceName ) ); | |||||
| if (baseSectionXml != null) | if (baseSectionXml != null) | ||||
| { | { | ||||
| Formatting matchFormatting = null, | Formatting matchFormatting = null, | ||||
| MatchFormattingOptions fo = MatchFormattingOptions.SubsetMatch, | MatchFormattingOptions fo = MatchFormattingOptions.SubsetMatch, | ||||
| bool escapeRegEx = true, | bool escapeRegEx = true, | ||||
| bool useRegExSubstitutions = false ) | |||||
| bool useRegExSubstitutions = false, | |||||
| bool removeEmptyParagraph = true ) | |||||
| { | { | ||||
| if( string.IsNullOrEmpty( searchValue ) ) | if( string.IsNullOrEmpty( searchValue ) ) | ||||
| { | { | ||||
| { | { | ||||
| foreach( Paragraph p in h.Paragraphs ) | foreach( Paragraph p in h.Paragraphs ) | ||||
| { | { | ||||
| p.ReplaceText( searchValue, newValue, trackChanges, options, newFormatting, matchFormatting, fo, escapeRegEx, useRegExSubstitutions ); | |||||
| p.ReplaceText( searchValue, newValue, trackChanges, options, newFormatting, matchFormatting, fo, escapeRegEx, useRegExSubstitutions, removeEmptyParagraph ); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| // ReplaceText int main body of document. | // ReplaceText int main body of document. | ||||
| foreach( Paragraph p in this.Paragraphs ) | foreach( Paragraph p in this.Paragraphs ) | ||||
| { | { | ||||
| p.ReplaceText( searchValue, newValue, trackChanges, options, newFormatting, matchFormatting, fo, escapeRegEx, useRegExSubstitutions ); | |||||
| p.ReplaceText( searchValue, newValue, trackChanges, options, newFormatting, matchFormatting, fo, escapeRegEx, useRegExSubstitutions, removeEmptyParagraph ); | |||||
| } | } | ||||
| // ReplaceText in Footers of the document. | // ReplaceText in Footers of the document. | ||||
| { | { | ||||
| foreach( Paragraph p in f.Paragraphs ) | foreach( Paragraph p in f.Paragraphs ) | ||||
| { | { | ||||
| p.ReplaceText( searchValue, newValue, trackChanges, options, newFormatting, matchFormatting, fo, escapeRegEx, useRegExSubstitutions ); | |||||
| p.ReplaceText( searchValue, newValue, trackChanges, options, newFormatting, matchFormatting, fo, escapeRegEx, useRegExSubstitutions, removeEmptyParagraph ); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /// <param name="newFormatting"></param> | /// <param name="newFormatting"></param> | ||||
| /// <param name="matchFormatting"></param> | /// <param name="matchFormatting"></param> | ||||
| /// <param name="fo"></param> | /// <param name="fo"></param> | ||||
| /// <param name="removeEmptyParagraph">Remove empty paragraph</param> | |||||
| public virtual void ReplaceText( string searchValue, | public virtual void ReplaceText( string searchValue, | ||||
| Func<string,string> regexMatchHandler, | Func<string,string> regexMatchHandler, | ||||
| bool trackChanges = false, | bool trackChanges = false, | ||||
| RegexOptions options = RegexOptions.None, | RegexOptions options = RegexOptions.None, | ||||
| Formatting newFormatting = null, | Formatting newFormatting = null, | ||||
| Formatting matchFormatting = null, | Formatting matchFormatting = null, | ||||
| MatchFormattingOptions fo = MatchFormattingOptions.SubsetMatch ) | |||||
| MatchFormattingOptions fo = MatchFormattingOptions.SubsetMatch, | |||||
| bool removeEmptyParagraph = true ) | |||||
| { | { | ||||
| if( string.IsNullOrEmpty( searchValue ) ) | if( string.IsNullOrEmpty( searchValue ) ) | ||||
| { | { | ||||
| { | { | ||||
| foreach( var p in hf.Paragraphs ) | foreach( var p in hf.Paragraphs ) | ||||
| { | { | ||||
| p.ReplaceText( searchValue, regexMatchHandler, trackChanges, options, newFormatting, matchFormatting, fo ); | |||||
| p.ReplaceText( searchValue, regexMatchHandler, trackChanges, options, newFormatting, matchFormatting, fo, removeEmptyParagraph ); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| foreach( var p in this.Paragraphs ) | foreach( var p in this.Paragraphs ) | ||||
| { | { | ||||
| p.ReplaceText( searchValue, regexMatchHandler, trackChanges, options, newFormatting, matchFormatting, fo ); | |||||
| p.ReplaceText( searchValue, regexMatchHandler, trackChanges, options, newFormatting, matchFormatting, fo, removeEmptyParagraph ); | |||||
| } | } | ||||
| } | } | ||||
| var listItemType = HelperFunctions.GetListItemType( p, Document ); | var listItemType = HelperFunctions.GetListItemType( p, Document ); | ||||
| if( listItemType != null ) | if( listItemType != null ) | ||||
| { | { | ||||
| p.ListItemType = GetListItemType( HelperFunctions.GetListItemType( p, Document ) ); | |||||
| p.ListItemType = GetListItemType( listItemType ); | |||||
| } | } | ||||
| } | } | ||||
| private float _pageSizeMultiplier = 20.0f; | private float _pageSizeMultiplier = 20.0f; | ||||
| private readonly object nextFreeDocPrIdLock = new object(); | |||||
| private long? nextFreeDocPrId; | |||||
| #endregion | |||||
| #region Internal Constants | |||||
| internal const string RelationshipImage = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"; | |||||
| internal const string ContentTypeApplicationRelationShipXml = "application/vnd.openxmlformats-package.relationships+xml"; | |||||
| #endregion | #endregion | ||||
| #region Internal Members | #region Internal Members | ||||
| /// </code> | /// </code> | ||||
| /// </example> | /// </example> | ||||
| /// <seealso cref="AddImage(string)"/> | /// <seealso cref="AddImage(string)"/> | ||||
| /// <seealso cref="AddImage(Stream)"/> | |||||
| /// <seealso cref="AddImage(Stream, string)"/> | |||||
| /// <seealso cref="Paragraph.Pictures"/> | /// <seealso cref="Paragraph.Pictures"/> | ||||
| /// <seealso cref="Paragraph.InsertPicture"/> | /// <seealso cref="Paragraph.InsertPicture"/> | ||||
| public List<Image> Images | public List<Image> Images | ||||
| { | { | ||||
| get | get | ||||
| { | { | ||||
| var imageRelationships = this.PackagePart.GetRelationshipsByType( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" ); | |||||
| var imageRelationships = this.PackagePart.GetRelationshipsByType( RelationshipImage ); | |||||
| if( imageRelationships.Any() ) | if( imageRelationships.Any() ) | ||||
| { | { | ||||
| return | return | ||||
| "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml", | "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml", | ||||
| "application/vnd.openxmlformats-package.core-properties+xml", | "application/vnd.openxmlformats-package.core-properties+xml", | ||||
| "application/vnd.openxmlformats-officedocument.extended-properties+xml", | "application/vnd.openxmlformats-officedocument.extended-properties+xml", | ||||
| "application/vnd.openxmlformats-package.relationships+xml" | |||||
| ContentTypeApplicationRelationShipXml | |||||
| }; | }; | ||||
| var imageContentTypes = new List<string> | var imageContentTypes = new List<string> | ||||
| using( FileStream fs = new FileStream( filename, FileMode.Open, FileAccess.Read, FileShare.Read ) ) | using( FileStream fs = new FileStream( filename, FileMode.Open, FileAccess.Read, FileShare.Read ) ) | ||||
| { | { | ||||
| var data = new byte[ fs.Length ]; | |||||
| fs.Read( data, 0, ( int )fs.Length ); | |||||
| ms.Write( data, 0, ( int )fs.Length ); | |||||
| CopyStream( fs, ms ); | |||||
| } | } | ||||
| // Open the docx package | // Open the docx package | ||||
| /// Add an Image into this document from a fully qualified or relative filename. | /// Add an Image into this document from a fully qualified or relative filename. | ||||
| /// </summary> | /// </summary> | ||||
| /// <param name="filename">The fully qualified or relative filename.</param> | /// <param name="filename">The fully qualified or relative filename.</param> | ||||
| /// <param name="contentType">MIME type of image, guessed if not given.</param> | |||||
| /// <returns>An Image file.</returns> | /// <returns>An Image file.</returns> | ||||
| /// <example> | /// <example> | ||||
| /// Add an Image into this document from a fully qualified filename. | /// Add an Image into this document from a fully qualified filename. | ||||
| /// }// Release this document from memory. | /// }// Release this document from memory. | ||||
| /// </code> | /// </code> | ||||
| /// </example> | /// </example> | ||||
| /// <seealso cref="AddImage(System.IO.Stream)"/> | |||||
| /// <seealso cref="AddImage(Stream, string)"/> | |||||
| /// <seealso cref="Paragraph.InsertPicture"/> | /// <seealso cref="Paragraph.InsertPicture"/> | ||||
| public Image AddImage( string filename ) | public Image AddImage( string filename ) | ||||
| { | { | ||||
| break; | break; | ||||
| } | } | ||||
| return AddImage( filename, contentType ); | |||||
| return AddImage( filename as object, contentType ); | |||||
| } | } | ||||
| /// <summary> | /// <summary> | ||||
| /// Add an Image into this document from a Stream. | /// Add an Image into this document from a Stream. | ||||
| /// </summary> | /// </summary> | ||||
| /// <param name="stream">A Stream stream.</param> | /// <param name="stream">A Stream stream.</param> | ||||
| /// <param name="contentType">MIME type of image.</param> | |||||
| /// <returns>An Image file.</returns> | /// <returns>An Image file.</returns> | ||||
| /// <example> | /// <example> | ||||
| /// Add an Image into a document using a Stream. | /// Add an Image into a document using a Stream. | ||||
| /// </example> | /// </example> | ||||
| /// <seealso cref="AddImage(string)"/> | /// <seealso cref="AddImage(string)"/> | ||||
| /// <seealso cref="Paragraph.InsertPicture"/> | /// <seealso cref="Paragraph.InsertPicture"/> | ||||
| public Image AddImage( Stream stream ) | |||||
| public Image AddImage( Stream stream, string contentType = "image/jpeg" ) | |||||
| { | { | ||||
| return AddImage( stream as object ); | |||||
| return AddImage( stream as object, contentType ); | |||||
| } | } | ||||
| /// <summary> | /// <summary> | ||||
| /// Adds a hyperlink to a document and creates a Paragraph which uses it. | |||||
| /// Adds a hyperlink with a uri to a document and creates a Paragraph which uses it. | |||||
| /// </summary> | /// </summary> | ||||
| /// <param name="text">The text as displayed by the hyperlink.</param> | /// <param name="text">The text as displayed by the hyperlink.</param> | ||||
| /// <param name="uri">The hyperlink itself.</param> | /// <param name="uri">The hyperlink itself.</param> | ||||
| /// <returns>Returns a hyperlink that can be inserted into a Paragraph.</returns> | |||||
| /// <returns>Returns a hyperlink with a uri that can be inserted into a Paragraph.</returns> | |||||
| /// <example> | /// <example> | ||||
| /// Adds a hyperlink to a document and creates a Paragraph which uses it. | /// Adds a hyperlink to a document and creates a Paragraph which uses it. | ||||
| /// <code> | /// <code> | ||||
| /// </example> | /// </example> | ||||
| public Hyperlink AddHyperlink( string text, Uri uri ) | public Hyperlink AddHyperlink( string text, Uri uri ) | ||||
| { | { | ||||
| var i = new XElement | |||||
| ( | |||||
| XName.Get( "hyperlink", w.NamespaceName ), | |||||
| new XAttribute( r + "id", string.Empty ), | |||||
| new XAttribute( w + "history", "1" ), | |||||
| new XElement( XName.Get( "r", w.NamespaceName ), | |||||
| new XElement( XName.Get( "rPr", w.NamespaceName ), | |||||
| new XElement( XName.Get( "rStyle", w.NamespaceName ), | |||||
| new XAttribute( w + "val", "Hyperlink" ) ) ), | |||||
| new XElement( XName.Get( "t", w.NamespaceName ), text ) ) | |||||
| ); | |||||
| var h = new Hyperlink( this, this.PackagePart, i ); | |||||
| h.text = text; | |||||
| h.uri = uri; | |||||
| this.AddHyperlinkStyleIfNotPresent(); | |||||
| return this.AddHyperlink( text, uri, null ); | |||||
| } | |||||
| return h; | |||||
| /// <summary> | |||||
| /// Adds a hyperlink with an anchor to a document and creates a Paragraph which uses it. | |||||
| /// </summary> | |||||
| /// <param name="text">The text as displayed by the hyperlink.</param> | |||||
| /// <param name="anchor">The anchor to a bookmark.</param> | |||||
| /// <returns>Returns a hyperlink with an anchor that can be inserted into a Paragraph.</returns> | |||||
| public Hyperlink AddHyperlink( string text, string anchor ) | |||||
| { | |||||
| return this.AddHyperlink( text, null, anchor ); | |||||
| } | } | ||||
| /// <summary> | /// <summary> | ||||
| { | { | ||||
| using( FileStream fs = new FileStream( _filename, FileMode.Create ) ) | using( FileStream fs = new FileStream( _filename, FileMode.Create ) ) | ||||
| { | { | ||||
| fs.Write( _memoryStream.ToArray(), 0, ( int )_memoryStream.Length ); | |||||
| if( _memoryStream.CanSeek ) | |||||
| { | |||||
| // Write to the beginning of the stream | |||||
| _memoryStream.Position = 0; | |||||
| CopyStream( _memoryStream, fs ); | |||||
| } | |||||
| else | |||||
| fs.Write( _memoryStream.ToArray(), 0, ( int )_memoryStream.Length ); | |||||
| } | } | ||||
| } | } | ||||
| else if( _stream.CanSeek ) //Check if stream can be seeked to support System.Web.HttpResponseStream. | else if( _stream.CanSeek ) //Check if stream can be seeked to support System.Web.HttpResponseStream. | ||||
| document.Document = document; | document.Document = document; | ||||
| #region MainDocumentPart | #region MainDocumentPart | ||||
| document.PackagePart = package.GetParts().Where | |||||
| ( | |||||
| p => p.ContentType.Equals( HelperFunctions.DOCUMENT_DOCUMENTTYPE, StringComparison.CurrentCultureIgnoreCase ) || | |||||
| p.ContentType.Equals( HelperFunctions.TEMPLATE_DOCUMENTTYPE, StringComparison.CurrentCultureIgnoreCase ) | |||||
| ).Single(); | |||||
| document.PackagePart = HelperFunctions.GetMainDocumentPart( package ); | |||||
| using( TextReader tr = new StreamReader( document.PackagePart.GetStream( FileMode.Open, FileAccess.Read ) ) ) | using( TextReader tr = new StreamReader( document.PackagePart.GetStream( FileMode.Open, FileAccess.Read ) ) ) | ||||
| { | { | ||||
| var newImageStream = ( o is string ) ? new FileStream( o as string, FileMode.Open, FileAccess.Read ) : o as Stream; | var newImageStream = ( o is string ) ? new FileStream( o as string, FileMode.Open, FileAccess.Read ) : o as Stream; | ||||
| // Get all image parts in word\document.xml | // Get all image parts in word\document.xml | ||||
| var ImageRelationships = this.PackagePart.GetRelationshipsByType( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" ); | |||||
| var imageParts = ImageRelationships.Select( ir => _package.GetParts().FirstOrDefault( p => p.Uri.ToString().EndsWith( ir.TargetUri.ToString() ) ) ) | |||||
| .Where( x => ( x != null ) ) | |||||
| .ToList(); | |||||
| PackagePartCollection packagePartCollection = _package.GetParts(); | |||||
| var parts = packagePartCollection.Select( x => new | |||||
| { | |||||
| UriString = x.Uri.ToString(), | |||||
| Part = x | |||||
| } ).ToList(); | |||||
| var partLookup = parts.ToDictionary( x => x.UriString, x => x.Part, StringComparer.Ordinal ); | |||||
| List<PackagePart> imageParts = new List<PackagePart>(); | |||||
| foreach( var item in this.PackagePart.GetRelationshipsByType( RelationshipImage ) ) | |||||
| { | |||||
| var targetUri = item.TargetUri.ToString(); | |||||
| PackagePart part; | |||||
| if( partLookup.TryGetValue( targetUri, out part ) ) | |||||
| { | |||||
| imageParts.Add( part ); | |||||
| } | |||||
| } | |||||
| IEnumerable<PackagePart> relsParts = parts | |||||
| .Where( | |||||
| part => | |||||
| part.Part.ContentType.Equals( ContentTypeApplicationRelationShipXml, StringComparison.Ordinal ) && | |||||
| part.UriString.IndexOf( "/word/", StringComparison.Ordinal ) > -1 ) | |||||
| .Select( part => part.Part ); | |||||
| XName xNameTarget = XName.Get( "Target" ); | |||||
| XName xNameTargetMode = XName.Get( "TargetMode" ); | |||||
| foreach( PackagePart relsPart in _package.GetParts().Where( part => part.Uri.ToString().Contains( "/word/" ) ).Where( part => part.ContentType.Equals( "application/vnd.openxmlformats-package.relationships+xml" ) ) ) | |||||
| foreach( PackagePart relsPart in relsParts ) | |||||
| { | { | ||||
| XDocument relsPartContent; | XDocument relsPartContent; | ||||
| using( TextReader tr = new StreamReader( relsPart.GetStream( FileMode.Open, FileAccess.Read ) ) ) | using( TextReader tr = new StreamReader( relsPart.GetStream( FileMode.Open, FileAccess.Read ) ) ) | ||||
| foreach( XElement imageRelationship in imageRelationships ) | foreach( XElement imageRelationship in imageRelationships ) | ||||
| { | { | ||||
| if( imageRelationship.Attribute( XName.Get( "Target" ) ) != null ) | |||||
| XAttribute attribute = imageRelationship.Attribute( xNameTarget ); | |||||
| if( attribute != null ) | |||||
| { | { | ||||
| var targetModeAttr = imageRelationship.Attribute( XName.Get( "TargetMode" ) ); | |||||
| var targetModeAttr = imageRelationship.Attribute( xNameTargetMode ); | |||||
| var targetMode = ( targetModeAttr != null ) ? targetModeAttr.Value : string.Empty; | var targetMode = ( targetModeAttr != null ) ? targetModeAttr.Value : string.Empty; | ||||
| if( !targetMode.Equals( "External" ) ) | if( !targetMode.Equals( "External" ) ) | ||||
| { | { | ||||
| var imagePartUri = Path.Combine( Path.GetDirectoryName( relsPart.Uri.ToString() ), imageRelationship.Attribute( XName.Get( "Target" ) ).Value ); | |||||
| var imagePartUri = Path.Combine( Path.GetDirectoryName( relsPart.Uri.ToString() ), attribute.Value ); | |||||
| imagePartUri = Path.GetFullPath( imagePartUri.Replace( "\\_rels", string.Empty ) ); | imagePartUri = Path.GetFullPath( imagePartUri.Replace( "\\_rels", string.Empty ) ); | ||||
| imagePartUri = imagePartUri.Replace( Path.GetFullPath( "\\" ), string.Empty ).Replace( "\\", "/" ); | imagePartUri = imagePartUri.Replace( Path.GetFullPath( "\\" ), string.Empty ).Replace( "\\", "/" ); | ||||
| // Loop through each image part in this document. | // Loop through each image part in this document. | ||||
| foreach( PackagePart pp in imageParts ) | foreach( PackagePart pp in imageParts ) | ||||
| { | { | ||||
| // Open a tempory Stream to this image part. | |||||
| // Get the image object for this image part. | |||||
| using( Stream tempStream = pp.GetStream( FileMode.Open, FileAccess.Read ) ) | using( Stream tempStream = pp.GetStream( FileMode.Open, FileAccess.Read ) ) | ||||
| { | { | ||||
| // Compare this image to the new image being added. | // Compare this image to the new image being added. | ||||
| if( HelperFunctions.IsSameFile( tempStream, newImageStream ) ) | if( HelperFunctions.IsSameFile( tempStream, newImageStream ) ) | ||||
| { | { | ||||
| // Get the image object for this image part | |||||
| var id = this.PackagePart.GetRelationshipsByType( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" ) | |||||
| .Where( r => r.TargetUri == pp.Uri ) | |||||
| .Select( r => r.Id ).First(); | |||||
| // Return the Image object | // Return the Image object | ||||
| return Images.Where( i => i.Id == id ).First(); | |||||
| PackageRelationship relationship = this.PackagePart.GetRelationshipsByType( RelationshipImage ).First( x => x.TargetUri == pp.Uri ); | |||||
| return new Image( this, relationship ); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } while( _package.PartExists( new Uri( imgPartUriPath, UriKind.Relative ) ) ); | } while( _package.PartExists( new Uri( imgPartUriPath, UriKind.Relative ) ) ); | ||||
| // We are now guareenteed that imgPartUriPath is unique. | |||||
| // We are now guaranteed that imgPartUriPath is unique. | |||||
| var img = _package.CreatePart( new Uri( imgPartUriPath, UriKind.Relative ), contentType, CompressionOption.Normal ); | var img = _package.CreatePart( new Uri( imgPartUriPath, UriKind.Relative ), contentType, CompressionOption.Normal ); | ||||
| // Create a new image relationship | // Create a new image relationship | ||||
| var rel = this.PackagePart.CreateRelationship( img.Uri, TargetMode.Internal, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" ); | |||||
| var rel = this.PackagePart.CreateRelationship( img.Uri, TargetMode.Internal, RelationshipImage ); | |||||
| // Open a Stream to the newly created Image part. | // Open a Stream to the newly created Image part. | ||||
| using( Stream stream = new PackagePartStream( img.GetStream( FileMode.Create, FileAccess.Write ) ) ) | using( Stream stream = new PackagePartStream( img.GetStream( FileMode.Create, FileAccess.Write ) ) ) | ||||
| // Using the Stream to the real image, copy this streams data into the newly create Image part. | // Using the Stream to the real image, copy this streams data into the newly create Image part. | ||||
| using( newImageStream ) | using( newImageStream ) | ||||
| { | { | ||||
| byte[] bytes = new byte[ newImageStream.Length ]; | |||||
| newImageStream.Read( bytes, 0, ( int )newImageStream.Length ); | |||||
| stream.Write( bytes, 0, ( int )newImageStream.Length ); | |||||
| CopyStream( newImageStream, stream, bufferSize: 4096 ); | |||||
| }// Close the Stream to the new image. | }// Close the Stream to the new image. | ||||
| }// Close the Stream to the new image part. | }// Close the Stream to the new image part. | ||||
| } | } | ||||
| } | } | ||||
| /// <summary> | |||||
| /// Finds the next free Id for bookmarkStart/docPr. | |||||
| /// </summary> | |||||
| internal long GetNextFreeDocPrId() | |||||
| { | |||||
| lock( nextFreeDocPrIdLock ) | |||||
| { | |||||
| if( nextFreeDocPrId != null ) | |||||
| { | |||||
| nextFreeDocPrId++; | |||||
| return nextFreeDocPrId.Value; | |||||
| } | |||||
| var xNameBookmarkStart = XName.Get( "bookmarkStart", DocX.w.NamespaceName ); | |||||
| var xNameDocPr = XName.Get( "docPr", DocX.wp.NamespaceName ); | |||||
| long newDocPrId = 1; | |||||
| HashSet<string> existingIds = new HashSet<string>(); | |||||
| foreach( var bookmarkId in Xml.Descendants() ) | |||||
| { | |||||
| if( bookmarkId.Name != xNameBookmarkStart && bookmarkId.Name != xNameDocPr ) | |||||
| continue; | |||||
| var idAtt = bookmarkId.Attributes().FirstOrDefault( x => x.Name.LocalName == "id" ); | |||||
| if( idAtt != null ) | |||||
| existingIds.Add( idAtt.Value ); | |||||
| } | |||||
| while( existingIds.Contains( newDocPrId.ToString() ) ) | |||||
| newDocPrId++; | |||||
| nextFreeDocPrId = newDocPrId; | |||||
| return nextFreeDocPrId.Value; | |||||
| } | |||||
| } | |||||
| #endregion | #endregion | ||||
| #region Private Methods | #region Private Methods | ||||
| { | { | ||||
| using( Stream s_write = new PackagePartStream( new_pp.GetStream( FileMode.Create ) ) ) | using( Stream s_write = new PackagePartStream( new_pp.GetStream( FileMode.Create ) ) ) | ||||
| { | { | ||||
| var buffer = new byte[ 32768 ]; | |||||
| int read; | |||||
| while( ( read = s_read.Read( buffer, 0, buffer.Length ) ) > 0 ) | |||||
| { | |||||
| s_write.Write( buffer, 0, read ); | |||||
| } | |||||
| CopyStream( s_read, s_write ); | |||||
| } | } | ||||
| } | } | ||||
| var pr = this.PackagePart.CreateRelationship( new Uri( new_uri, UriKind.Relative ), TargetMode.Internal, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" ); | |||||
| var pr = this.PackagePart.CreateRelationship( new Uri( new_uri, UriKind.Relative ), TargetMode.Internal, RelationshipImage ); | |||||
| var new_Id = pr.Id; | var new_Id = pr.Id; | ||||
| private void merge_numbering( PackagePart remote_pp, PackagePart local_pp, XDocument remote_mainDoc, DocX remote ) | private void merge_numbering( PackagePart remote_pp, PackagePart local_pp, XDocument remote_mainDoc, DocX remote ) | ||||
| { | { | ||||
| // Add each remote numbering to this document. | // Add each remote numbering to this document. | ||||
| var abstractNumElement = _numbering.Root.Elements( XName.Get( "abstractNum", w.NamespaceName ) ); | |||||
| var remote_abstractNums = remote._numbering.Root.Elements( XName.Get( "abstractNum", w.NamespaceName ) ); | var remote_abstractNums = remote._numbering.Root.Elements( XName.Get( "abstractNum", w.NamespaceName ) ); | ||||
| int guidd = 0; | |||||
| foreach( var an in remote_abstractNums ) | |||||
| int guidd = -1; | |||||
| foreach( var an in abstractNumElement ) | |||||
| { | { | ||||
| var a = an.Attribute( XName.Get( "abstractNumId", w.NamespaceName ) ); | var a = an.Attribute( XName.Get( "abstractNumId", w.NamespaceName ) ); | ||||
| if( a != null ) | if( a != null ) | ||||
| guidd++; | guidd++; | ||||
| var remote_nums = remote._numbering.Root.Elements( XName.Get( "num", w.NamespaceName ) ); | var remote_nums = remote._numbering.Root.Elements( XName.Get( "num", w.NamespaceName ) ); | ||||
| var numElement = _numbering.Root.Elements( XName.Get( "num", w.NamespaceName ) ); | |||||
| int guidd2 = 0; | int guidd2 = 0; | ||||
| foreach( var an in remote_nums ) | |||||
| foreach( var an in numElement ) | |||||
| { | { | ||||
| var a = an.Attribute( XName.Get( "numId", w.NamespaceName ) ); | var a = an.Attribute( XName.Get( "numId", w.NamespaceName ) ); | ||||
| if( a != null ) | if( a != null ) | ||||
| foreach( XElement remote_abstractNum in remote_abstractNums ) | foreach( XElement remote_abstractNum in remote_abstractNums ) | ||||
| { | { | ||||
| var currentGuidd2 = guidd2; | |||||
| var abstractNumId = remote_abstractNum.Attribute( XName.Get( "abstractNumId", w.NamespaceName ) ); | var abstractNumId = remote_abstractNum.Attribute( XName.Get( "abstractNumId", w.NamespaceName ) ); | ||||
| if( abstractNumId != null ) | if( abstractNumId != null ) | ||||
| { | { | ||||
| foreach( XElement remote_num in remote_nums ) | foreach( XElement remote_num in remote_nums ) | ||||
| { | { | ||||
| // in document | |||||
| var numIds = remote_mainDoc.Descendants( XName.Get( "numId", w.NamespaceName ) ); | var numIds = remote_mainDoc.Descendants( XName.Get( "numId", w.NamespaceName ) ); | ||||
| foreach( var numId in numIds ) | foreach( var numId in numIds ) | ||||
| { | { | ||||
| var attr = numId.Attribute( XName.Get( "val", w.NamespaceName ) ); | var attr = numId.Attribute( XName.Get( "val", w.NamespaceName ) ); | ||||
| if( attr != null && attr.Value.Equals( remote_num.Attribute( XName.Get( "numId", w.NamespaceName ) ).Value ) ) | if( attr != null && attr.Value.Equals( remote_num.Attribute( XName.Get( "numId", w.NamespaceName ) ).Value ) ) | ||||
| { | { | ||||
| attr.SetValue( guidd2 ); | |||||
| attr.SetValue( currentGuidd2 ); | |||||
| } | } | ||||
| } | } | ||||
| remote_num.SetAttributeValue( XName.Get( "numId", w.NamespaceName ), guidd2 ); | |||||
| remote_num.SetAttributeValue( XName.Get( "numId", w.NamespaceName ), currentGuidd2 ); | |||||
| //abstractNumId of this remote_num | |||||
| var e = remote_num.Element( XName.Get( "abstractNumId", w.NamespaceName ) ); | var e = remote_num.Element( XName.Get( "abstractNumId", w.NamespaceName ) ); | ||||
| var a2 = e.Attribute( XName.Get( "val", w.NamespaceName ) ); | var a2 = e.Attribute( XName.Get( "val", w.NamespaceName ) ); | ||||
| if ( a2 != null && a2.Value.Equals( abstractNumIdValue ) ) | |||||
| if( a2 != null && a2.Value.Equals( abstractNumIdValue ) ) | |||||
| a2.SetValue( guidd ); | a2.SetValue( guidd ); | ||||
| guidd2++; | |||||
| currentGuidd2++; | |||||
| } | } | ||||
| } | } | ||||
| guidd++; | guidd++; | ||||
| } | } | ||||
| var abstractNumElement = _numbering.Root.Elements( XName.Get( "abstractNum", w.NamespaceName ) ); | |||||
| if( ( abstractNumElement != null ) && ( abstractNumElement.Count() > 0 ) ) | |||||
| if( abstractNumElement != null ) | |||||
| { | { | ||||
| abstractNumElement.Last().AddAfterSelf( remote_abstractNums ); | |||||
| if( abstractNumElement.Count() > 0 ) | |||||
| { | |||||
| abstractNumElement.Last().AddAfterSelf( remote_abstractNums ); | |||||
| } | |||||
| else | |||||
| { | |||||
| _numbering.Root.Add( remote_abstractNums ); | |||||
| } | |||||
| } | } | ||||
| var numElement = _numbering.Root.Elements( XName.Get( "num", w.NamespaceName ) ); | |||||
| if( ( numElement != null ) && ( numElement.Count() > 0 ) ) | |||||
| if( numElement != null ) | |||||
| { | { | ||||
| numElement.Last().AddAfterSelf( remote_nums ); | |||||
| if( numElement.Count() > 0 ) | |||||
| { | |||||
| numElement.Last().AddAfterSelf( remote_nums ); | |||||
| } | |||||
| else | |||||
| { | |||||
| _numbering.Root.Add( remote_nums ); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| { | { | ||||
| using( Stream s_write = new PackagePartStream( new_pp.GetStream( FileMode.Create ) ) ) | using( Stream s_write = new PackagePartStream( new_pp.GetStream( FileMode.Create ) ) ) | ||||
| { | { | ||||
| var buffer = new byte[ 32768 ]; | |||||
| int read; | |||||
| while( ( read = s_read.Read( buffer, 0, buffer.Length ) ) > 0 ) | |||||
| { | |||||
| s_write.Write( buffer, 0, read ); | |||||
| } | |||||
| CopyStream( s_read, s_write ); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| private static void CopyStream( Stream input, Stream output, int bufferSize = 32768 ) | |||||
| { | |||||
| byte[] buffer = new byte[ bufferSize ]; | |||||
| int read; | |||||
| while( ( read = input.Read( buffer, 0, buffer.Length ) ) > 0 ) | |||||
| { | |||||
| output.Write( buffer, 0, read ); | |||||
| } | |||||
| } | |||||
| private string GetNextFreeRelationshipID() | private string GetNextFreeRelationshipID() | ||||
| { | { | ||||
| int id = | int id = | ||||
| return result; | return result; | ||||
| } | } | ||||
| private Hyperlink AddHyperlink( string text, Uri uri, string anchor ) | |||||
| { | |||||
| var i = new XElement | |||||
| ( | |||||
| XName.Get( "hyperlink", w.NamespaceName ), | |||||
| new XAttribute( r + "id", string.Empty ), | |||||
| new XAttribute( w + "history", "1" ), | |||||
| !string.IsNullOrEmpty( anchor ) ? new XAttribute( w + "anchor", anchor ) : null, | |||||
| new XElement( XName.Get( "r", w.NamespaceName ), | |||||
| new XElement( XName.Get( "rPr", w.NamespaceName ), | |||||
| new XElement( XName.Get( "rStyle", w.NamespaceName ), | |||||
| new XAttribute( w + "val", "Hyperlink" ) ) ), | |||||
| new XElement( XName.Get( "t", w.NamespaceName ), text ) ) | |||||
| ); | |||||
| var h = new Hyperlink( this, this.PackagePart, i ); | |||||
| h.text = text; | |||||
| if( uri != null ) | |||||
| { | |||||
| h.uri = uri; | |||||
| } | |||||
| this.AddHyperlinkStyleIfNotPresent(); | |||||
| return h; | |||||
| } | |||||
| #endregion | #endregion | ||||
| #region Constructors | #region Constructors |
| using System; | using System; | ||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| using System.Linq; | |||||
| using System.Xml.Linq; | using System.Xml.Linq; | ||||
| using System.IO.Packaging; | using System.IO.Packaging; | ||||
| using System.Collections.ObjectModel; | using System.Collections.ObjectModel; | ||||
| } | } | ||||
| } | } | ||||
| public List<Image> Images | |||||
| { | |||||
| get | |||||
| { | |||||
| var imageRelationships = this.PackagePart.GetRelationshipsByType( DocX.RelationshipImage ); | |||||
| if( imageRelationships.Count() > 0 ) | |||||
| { | |||||
| return | |||||
| ( | |||||
| from i in imageRelationships | |||||
| select new Image( Document, i ) | |||||
| ).ToList(); | |||||
| } | |||||
| return new List<Image>(); | |||||
| } | |||||
| } | |||||
| #endregion | #endregion | ||||
| #region Constructors | #region Constructors |
| private StrikeThrough? _strikethrough; | private StrikeThrough? _strikethrough; | ||||
| private Script? _script; | private Script? _script; | ||||
| private Highlight? _highlight; | private Highlight? _highlight; | ||||
| private Color? _shading; | |||||
| private double? _size; | private double? _size; | ||||
| private Color? _fontColor; | private Color? _fontColor; | ||||
| private Color? _underlineColor; | private Color? _underlineColor; | ||||
| private int? _kerning; | private int? _kerning; | ||||
| private int? _position; | private int? _position; | ||||
| private double? _spacing; | private double? _spacing; | ||||
| private string _styleName; | |||||
| private CultureInfo _language; | private CultureInfo _language; | ||||
| } | } | ||||
| } | } | ||||
| /// <summary> | |||||
| /// Shading color. | |||||
| /// </summary> | |||||
| public Color? Shading | |||||
| { | |||||
| get | |||||
| { | |||||
| return _shading; | |||||
| } | |||||
| set | |||||
| { | |||||
| _shading = value; | |||||
| } | |||||
| } | |||||
| public string StyleName | |||||
| { | |||||
| get | |||||
| { | |||||
| return _styleName; | |||||
| } | |||||
| set | |||||
| { | |||||
| _styleName = value; | |||||
| } | |||||
| } | |||||
| /// <summary> | /// <summary> | ||||
| /// The Underline style that this formatting applies. | /// The Underline style that this formatting applies. | ||||
| /// </summary> | /// </summary> | ||||
| _rPr.Add( new XElement( XName.Get( "spacing", DocX.w.NamespaceName ), new XAttribute( XName.Get( "val", DocX.w.NamespaceName ), _spacing.Value * 20 ) ) ); | _rPr.Add( new XElement( XName.Get( "spacing", DocX.w.NamespaceName ), new XAttribute( XName.Get( "val", DocX.w.NamespaceName ), _spacing.Value * 20 ) ) ); | ||||
| } | } | ||||
| if( !string.IsNullOrEmpty( _styleName ) ) | |||||
| { | |||||
| _rPr.Add( new XElement( XName.Get( "rStyle", DocX.w.NamespaceName ), new XAttribute( XName.Get( "val", DocX.w.NamespaceName ), _styleName ) ) ); | |||||
| } | |||||
| if( _position.HasValue ) | if( _position.HasValue ) | ||||
| { | { | ||||
| _rPr.Add( new XElement( XName.Get( "position", DocX.w.NamespaceName ), new XAttribute( XName.Get( "val", DocX.w.NamespaceName ), _position.Value * 2 ) ) ); | _rPr.Add( new XElement( XName.Get( "position", DocX.w.NamespaceName ), new XAttribute( XName.Get( "val", DocX.w.NamespaceName ), _position.Value * 2 ) ) ); | ||||
| ( | ( | ||||
| new XElement( XName.Get( "rFonts", DocX.w.NamespaceName ), new XAttribute( XName.Get( "ascii", DocX.w.NamespaceName ), _fontFamily.Name ), | new XElement( XName.Get( "rFonts", DocX.w.NamespaceName ), new XAttribute( XName.Get( "ascii", DocX.w.NamespaceName ), _fontFamily.Name ), | ||||
| new XAttribute( XName.Get( "hAnsi", DocX.w.NamespaceName ), _fontFamily.Name ), | new XAttribute( XName.Get( "hAnsi", DocX.w.NamespaceName ), _fontFamily.Name ), | ||||
| new XAttribute( XName.Get( "cs", DocX.w.NamespaceName ), _fontFamily.Name ) ) | |||||
| new XAttribute( XName.Get( "cs", DocX.w.NamespaceName ), _fontFamily.Name ), | |||||
| new XAttribute( XName.Get( "eastAsia", DocX.w.NamespaceName ), _fontFamily.Name ) ) | |||||
| ); | ); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if( _shading.HasValue ) | |||||
| { | |||||
| _rPr.Add( new XElement( XName.Get( "shd", DocX.w.NamespaceName ), new XAttribute( XName.Get( "fill", DocX.w.NamespaceName ), _shading.Value.ToHex() ) ) ); | |||||
| } | |||||
| if( _capsStyle.HasValue ) | if( _capsStyle.HasValue ) | ||||
| { | { | ||||
| switch( _capsStyle ) | switch( _capsStyle ) | ||||
| clone.FontFamily = _fontFamily; | clone.FontFamily = _fontFamily; | ||||
| clone.Hidden = _hidden; | clone.Hidden = _hidden; | ||||
| clone.Highlight = _highlight; | clone.Highlight = _highlight; | ||||
| clone.Shading = _shading; | |||||
| clone.Italic = _italic; | clone.Italic = _italic; | ||||
| if( _kerning.HasValue ) | if( _kerning.HasValue ) | ||||
| { | { | ||||
| { | { | ||||
| clone.Spacing = _spacing; | clone.Spacing = _spacing; | ||||
| } | } | ||||
| if( !string.IsNullOrEmpty( _styleName ) ) | |||||
| { | |||||
| clone.StyleName = _styleName; | |||||
| } | |||||
| clone.StrikeThrough = _strikethrough; | clone.StrikeThrough = _strikethrough; | ||||
| clone.UnderlineColor = _underlineColor; | clone.UnderlineColor = _underlineColor; | ||||
| clone.UnderlineStyle = _underlineStyle; | clone.UnderlineStyle = _underlineStyle; | ||||
| } | } | ||||
| public static Formatting Parse( XElement rPr ) | |||||
| public static Formatting Parse( XElement rPr, Formatting formatting = null ) | |||||
| { | { | ||||
| var formatting = new Formatting(); | |||||
| if( formatting == null ) | |||||
| { | |||||
| formatting = new Formatting(); | |||||
| } | |||||
| if( rPr == null ) | |||||
| return formatting; | |||||
| // Build up the Formatting object. | // Build up the Formatting object. | ||||
| foreach( XElement option in rPr.Elements() ) | foreach( XElement option in rPr.Elements() ) | ||||
| formatting.Position = Int32.Parse(option.GetAttribute(XName.Get("val", DocX.w.NamespaceName))) / 2; | formatting.Position = Int32.Parse(option.GetAttribute(XName.Get("val", DocX.w.NamespaceName))) / 2; | ||||
| break; | break; | ||||
| case "kern": | case "kern": | ||||
| formatting.Position = Int32.Parse(option.GetAttribute(XName.Get("val", DocX.w.NamespaceName))) / 2; | |||||
| formatting.Kerning = Int32.Parse(option.GetAttribute(XName.Get("val", DocX.w.NamespaceName))) / 2; | |||||
| break; | break; | ||||
| case "w": | case "w": | ||||
| formatting.PercentageScale = Int32.Parse(option.GetAttribute(XName.Get("val", DocX.w.NamespaceName))); | formatting.PercentageScale = Int32.Parse(option.GetAttribute(XName.Get("val", DocX.w.NamespaceName))); | ||||
| formatting.Size = Int32.Parse(option.GetAttribute(XName.Get("val", DocX.w.NamespaceName))) / 2; | formatting.Size = Int32.Parse(option.GetAttribute(XName.Get("val", DocX.w.NamespaceName))) / 2; | ||||
| break; | break; | ||||
| case "rFonts": | case "rFonts": | ||||
| formatting.FontFamily = new Font(option.GetAttribute(XName.Get("cs", DocX.w.NamespaceName), null) ?? option.GetAttribute(XName.Get("ascii", DocX.w.NamespaceName), null) ?? option.GetAttribute(XName.Get("hAnsi", DocX.w.NamespaceName), null) ?? option.GetAttribute(XName.Get("eastAsia", DocX.w.NamespaceName))); | |||||
| var fontName = option.GetAttribute( XName.Get( "cs", DocX.w.NamespaceName ), null ) | |||||
| ?? option.GetAttribute( XName.Get( "ascii", DocX.w.NamespaceName ), null ) | |||||
| ?? option.GetAttribute( XName.Get( "hAnsi", DocX.w.NamespaceName ), null ) | |||||
| ?? option.GetAttribute( XName.Get( "hint", DocX.w.NamespaceName ), null ) | |||||
| ?? option.GetAttribute( XName.Get( "eastAsia", DocX.w.NamespaceName ), null ); | |||||
| formatting.FontFamily = new Font( fontName ?? "Calibri" ); | |||||
| break; | break; | ||||
| case "color": | case "color": | ||||
| try | try | ||||
| { | { | ||||
| var color = option.GetAttribute(XName.Get("val", DocX.w.NamespaceName)); | var color = option.GetAttribute(XName.Get("val", DocX.w.NamespaceName)); | ||||
| formatting.FontColor = System.Drawing.ColorTranslator.FromHtml(string.Format("#{0}", color)); | |||||
| formatting.FontColor = ( color == "auto") ? Color.Black : ColorTranslator.FromHtml(string.Format("#{0}", color)); | |||||
| } | } | ||||
| catch (Exception) | catch (Exception) | ||||
| { | { | ||||
| formatting._hidden = true; | formatting._hidden = true; | ||||
| break; | break; | ||||
| case "b": | case "b": | ||||
| formatting.Bold = true; | |||||
| formatting.Bold = option.GetAttribute( XName.Get( "val", DocX.w.NamespaceName ) ) != "0"; | |||||
| break; | break; | ||||
| case "i": | case "i": | ||||
| formatting.Italic = true; | formatting.Italic = true; | ||||
| case "strike": | case "strike": | ||||
| formatting.StrikeThrough = NET.StrikeThrough.strike; | formatting.StrikeThrough = NET.StrikeThrough.strike; | ||||
| break; | break; | ||||
| case "dstrike": | |||||
| formatting.StrikeThrough = NET.StrikeThrough.doubleStrike; | |||||
| break; | |||||
| case "u": | case "u": | ||||
| formatting.UnderlineStyle = HelperFunctions.GetUnderlineStyle(option.GetAttribute(XName.Get("val", DocX.w.NamespaceName))); | formatting.UnderlineStyle = HelperFunctions.GetUnderlineStyle(option.GetAttribute(XName.Get("val", DocX.w.NamespaceName))); | ||||
| try | |||||
| { | |||||
| var color = option.GetAttribute( XName.Get( "color", DocX.w.NamespaceName ) ); | |||||
| if( !string.IsNullOrEmpty( color ) ) | |||||
| { | |||||
| formatting.UnderlineColor = System.Drawing.ColorTranslator.FromHtml( string.Format( "#{0}", color ) ); | |||||
| } | |||||
| } | |||||
| catch( Exception ) | |||||
| { | |||||
| // ignore | |||||
| } | |||||
| break; | break; | ||||
| case "vertAlign": | |||||
| case "vertAlign": //script | |||||
| var script = option.GetAttribute(XName.Get("val", DocX.w.NamespaceName), null); | var script = option.GetAttribute(XName.Get("val", DocX.w.NamespaceName), null); | ||||
| formatting.Script = (Script)Enum.Parse(typeof(Script), script); | formatting.Script = (Script)Enum.Parse(typeof(Script), script); | ||||
| break; | break; | ||||
| case "caps": | |||||
| formatting.CapsStyle = NET.CapsStyle.caps; | |||||
| break; | |||||
| case "smallCaps": | |||||
| formatting.CapsStyle = NET.CapsStyle.smallCaps; | |||||
| break; | |||||
| case "shd": | |||||
| var fill = option.GetAttribute( XName.Get( "fill", DocX.w.NamespaceName ) ); | |||||
| if( !string.IsNullOrEmpty( fill ) ) | |||||
| { | |||||
| formatting.Shading = System.Drawing.ColorTranslator.FromHtml( string.Format( "#{0}", fill ) ); | |||||
| } | |||||
| break; | |||||
| case "rStyle": | |||||
| var style = option.GetAttribute( XName.Get( "val", DocX.w.NamespaceName ), null ); | |||||
| formatting.StyleName = style; | |||||
| break; | |||||
| default: | default: | ||||
| break; | break; | ||||
| } | } | ||||
| if( other._highlight != _highlight ) | if( other._highlight != _highlight ) | ||||
| return -1; | return -1; | ||||
| if( other._shading != _shading ) | |||||
| return -1; | |||||
| if( other._size != _size ) | if( other._size != _size ) | ||||
| return -1; | return -1; | ||||
| if( other._spacing != _spacing ) | if( other._spacing != _spacing ) | ||||
| return -1; | return -1; | ||||
| if( other._styleName != _styleName ) | |||||
| return -1; | |||||
| if( !other._language.Equals(_language) ) | if( !other._language.Equals(_language) ) | ||||
| return -1; | return -1; | ||||
| { | { | ||||
| get | get | ||||
| { | { | ||||
| var imageRelationships = this.PackagePart.GetRelationshipsByType( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" ); | |||||
| var imageRelationships = this.PackagePart.GetRelationshipsByType( DocX.RelationshipImage ); | |||||
| if( imageRelationships.Count() > 0 ) | if( imageRelationships.Count() > 0 ) | ||||
| { | { | ||||
| return | return |
| public const string DOCUMENT_DOCUMENTTYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"; | public const string DOCUMENT_DOCUMENTTYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"; | ||||
| public const string TEMPLATE_DOCUMENTTYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml"; | public const string TEMPLATE_DOCUMENTTYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml"; | ||||
| public const string SETTING_DOCUMENTTYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"; | public const string SETTING_DOCUMENTTYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"; | ||||
| public const string MACRO_DOCUMENTTYPE = "application/vnd.ms-word.document.macroEnabled.main+xml"; | |||||
| internal static readonly char[] RestrictedXmlCharacters = new char[] | |||||
| { | |||||
| '\x1','\x2','\x3','\x4','\x5','\x6','\x7','\x8','\xb','\xc','\xe','\xf', | |||||
| '\x10','\x11','\x12','\x13','\x14','\x15','\x16','\x17','\x18','\x19','\x1a','\x1b','\x1c','\x1e','\x1f', | |||||
| '\x7f','\x80','\x81','\x82','\x83','\x84','\x86','\x87','\x88','\x89','\x8a','\x8b','\x8c','\x8d','\x8e','\x8f', | |||||
| '\x90','\x91','\x92','\x93','\x94','\x95','\x96','\x97','\x98','\x99','\x9a','\x9b','\x9c','\x9d','\x9e','\x9f' | |||||
| }; | |||||
| internal static void CreateRelsPackagePart( DocX Document, Uri uri ) | internal static void CreateRelsPackagePart( DocX Document, Uri uri ) | ||||
| { | { | ||||
| PackagePart pp = Document._package.CreatePart( uri, "application/vnd.openxmlformats-package.relationships+xml", CompressionOption.Maximum ); | |||||
| PackagePart pp = Document._package.CreatePart( uri, DocX.ContentTypeApplicationRelationShipXml, CompressionOption.Maximum ); | |||||
| using( TextWriter tw = new StreamWriter( new PackagePartStream( pp.GetStream() ) ) ) | using( TextWriter tw = new StreamWriter( new PackagePartStream( pp.GetStream() ) ) ) | ||||
| { | { | ||||
| XDocument d = new XDocument | XDocument d = new XDocument | ||||
| switch( Xml.Name.LocalName ) | switch( Xml.Name.LocalName ) | ||||
| { | { | ||||
| case "tab": | case "tab": | ||||
| return 1; | |||||
| return (Xml.Parent.Name.LocalName != "tabs" ) ? 1 : 0; | |||||
| case "br": | case "br": | ||||
| return 1; | return 1; | ||||
| case "t": | case "t": | ||||
| return null; | return null; | ||||
| // e is a w:t element, it must exist inside a w:r element or a w:tabs, lets climb until we find it. | // e is a w:t element, it must exist inside a w:r element or a w:tabs, lets climb until we find it. | ||||
| while( !e.Name.Equals( XName.Get( "r", DocX.w.NamespaceName ) ) && !e.Name.Equals( XName.Get( "tabs", DocX.w.NamespaceName ) ) ) | |||||
| while( (e != null) && !e.Name.Equals( XName.Get( "r", DocX.w.NamespaceName ) ) && !e.Name.Equals( XName.Get( "tabs", DocX.w.NamespaceName ) ) ) | |||||
| e = e.Parent; | e = e.Parent; | ||||
| // e is a w:r element, lets find the rPr element. | |||||
| XElement rPr = e.Element( XName.Get( "rPr", DocX.w.NamespaceName ) ); | |||||
| FormattedText ft = new FormattedText(); | FormattedText ft = new FormattedText(); | ||||
| ft.text = text; | ft.text = text; | ||||
| ft.index = 0; | ft.index = 0; | ||||
| ft.formatting = null; | ft.formatting = null; | ||||
| // Return text with formatting. | |||||
| if( rPr != null ) | |||||
| ft.formatting = Formatting.Parse( rPr ); | |||||
| if( e != null ) | |||||
| { | |||||
| // e is a w:r element, lets find the rPr element. | |||||
| XElement rPr = e.Element( XName.Get( "rPr", DocX.w.NamespaceName ) ); | |||||
| // Return text with formatting. | |||||
| if( rPr != null ) | |||||
| ft.formatting = Formatting.Parse( rPr ); | |||||
| } | |||||
| return ft; | return ft; | ||||
| } | } | ||||
| switch( e.Name.LocalName ) | switch( e.Name.LocalName ) | ||||
| { | { | ||||
| case "tab": | case "tab": | ||||
| return "\t"; | |||||
| // Do not add "\t" for TabStopPositions defined in "tabs". | |||||
| return ((e.Parent != null) && e.Parent.Name.Equals( XName.Get( "tabs", DocX.w.NamespaceName ) )) ? "" : "\t"; | |||||
| case "br": | case "br": | ||||
| return "\n"; | return "\n"; | ||||
| case "t": | case "t": | ||||
| goto case "delText"; | goto case "delText"; | ||||
| case "delText": | case "delText": | ||||
| { | { | ||||
| if( e.Parent != null && e.Parent.Name.LocalName == "r" ) | |||||
| { | |||||
| XElement run = e.Parent; | |||||
| var rPr = run.Elements().FirstOrDefault( a => a.Name.LocalName == "rPr" ); | |||||
| if( rPr != null ) | |||||
| { | |||||
| var caps = rPr.Elements().FirstOrDefault( a => a.Name.LocalName == "caps" ); | |||||
| if( caps != null ) | |||||
| return e.Value.ToUpper(); | |||||
| } | |||||
| } | |||||
| return e.Value; | return e.Value; | ||||
| } | } | ||||
| ); | ); | ||||
| } | } | ||||
| internal static PackagePart GetMainDocumentPart( Package package ) | |||||
| { | |||||
| return package.GetParts().Single( p => p.ContentType.Equals( DOCUMENT_DOCUMENTTYPE, StringComparison.CurrentCultureIgnoreCase ) || | |||||
| p.ContentType.Equals( TEMPLATE_DOCUMENTTYPE, StringComparison.CurrentCultureIgnoreCase ) || | |||||
| p.ContentType.Equals( MACRO_DOCUMENTTYPE, StringComparison.CurrentCultureIgnoreCase ) ); | |||||
| } | |||||
| internal static PackagePart CreateOrGetSettingsPart( Package package ) | internal static PackagePart CreateOrGetSettingsPart( Package package ) | ||||
| { | { | ||||
| PackagePart settingsPart; | PackagePart settingsPart; | ||||
| { | { | ||||
| settingsPart = package.CreatePart( settingsUri, HelperFunctions.SETTING_DOCUMENTTYPE, CompressionOption.Maximum ); | settingsPart = package.CreatePart( settingsUri, HelperFunctions.SETTING_DOCUMENTTYPE, CompressionOption.Maximum ); | ||||
| var mainDocPart = package.GetParts().Single( p => p.ContentType.Equals( DOCUMENT_DOCUMENTTYPE, StringComparison.CurrentCultureIgnoreCase ) || | |||||
| p.ContentType.Equals( TEMPLATE_DOCUMENTTYPE, StringComparison.CurrentCultureIgnoreCase ) ); | |||||
| var mainDocPart = GetMainDocumentPart( package ); | |||||
| mainDocPart.CreateRelationship( settingsUri, TargetMode.Internal, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings" ); | mainDocPart.CreateRelationship( settingsUri, TargetMode.Internal, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings" ); | ||||
| stylesDoc.Save( tw, SaveOptions.None ); | stylesDoc.Save( tw, SaveOptions.None ); | ||||
| } | } | ||||
| var mainDocumentPart = package.GetParts().Where | |||||
| ( | |||||
| p => p.ContentType.Equals( DOCUMENT_DOCUMENTTYPE, StringComparison.CurrentCultureIgnoreCase ) || | |||||
| p.ContentType.Equals( TEMPLATE_DOCUMENTTYPE, StringComparison.CurrentCultureIgnoreCase ) | |||||
| ).Single(); | |||||
| var mainDocumentPart = GetMainDocumentPart( package ); | |||||
| mainDocumentPart.CreateRelationship( word_styles.Uri, TargetMode.Internal, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" ); | mainDocumentPart.CreateRelationship( word_styles.Uri, TargetMode.Internal, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" ); | ||||
| return stylesDoc; | return stylesDoc; | ||||
| internal static Paragraph GetFirstParagraphEffectedByInsert( DocX document, int index ) | internal static Paragraph GetFirstParagraphEffectedByInsert( DocX document, int index ) | ||||
| { | { | ||||
| // This document contains no Paragraphs and insertion is at index 0 | // This document contains no Paragraphs and insertion is at index 0 | ||||
| if( document._paragraphLookup.Keys.Count() == 0 && index == 0 ) | |||||
| if( document.Paragraphs.Count() == 0 && index == 0 ) | |||||
| return null; | return null; | ||||
| foreach( int paragraphEndIndex in document._paragraphLookup.Keys ) | |||||
| foreach( Paragraph p in document.Paragraphs ) | |||||
| { | { | ||||
| if( paragraphEndIndex >= index ) | |||||
| return document._paragraphLookup[ paragraphEndIndex ]; | |||||
| if( p._endIndex >= index ) | |||||
| return p; | |||||
| } | } | ||||
| throw new ArgumentOutOfRangeException(); | throw new ArgumentOutOfRangeException(); | ||||
| break; | break; | ||||
| default: | default: | ||||
| sb.Append( c ); | |||||
| if( !RestrictedXmlCharacters.Contains( c ) ) | |||||
| sb.Append( c ); | |||||
| break; | break; | ||||
| } | } | ||||
| numberingDoc.Save( tw, SaveOptions.None ); | numberingDoc.Save( tw, SaveOptions.None ); | ||||
| } | } | ||||
| var mainDocPart = package.GetParts().Single( p => p.ContentType.Equals( DOCUMENT_DOCUMENTTYPE, StringComparison.CurrentCultureIgnoreCase ) || | |||||
| p.ContentType.Equals( TEMPLATE_DOCUMENTTYPE, StringComparison.CurrentCultureIgnoreCase ) ); | |||||
| var mainDocPart = GetMainDocumentPart( package ); | |||||
| mainDocPart.CreateRelationship(numberingPart.Uri, TargetMode.Internal, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering"); | mainDocPart.CreateRelationship(numberingPart.Uri, TargetMode.Internal, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering"); | ||||
| return numberingDoc; | return numberingDoc; | ||||
| internal static string GetListItemType( Paragraph p, DocX document ) | internal static string GetListItemType( Paragraph p, DocX document ) | ||||
| { | { | ||||
| var ilvlNode = p.ParagraphNumberProperties.Descendants().FirstOrDefault( el => el.Name.LocalName == "ilvl" ); | |||||
| var ilvlValue = ilvlNode.Attribute( DocX.w + "val" ).Value; | |||||
| var paragraphNumberPropertiesDescendants = p.ParagraphNumberProperties.Descendants(); | |||||
| var ilvlNode = paragraphNumberPropertiesDescendants.FirstOrDefault( el => el.Name.LocalName == "ilvl" ); | |||||
| var ilvlValue = ( ilvlNode != null) ? ilvlNode.Attribute( DocX.w + "val" ).Value : null; | |||||
| var numIdNode = p.ParagraphNumberProperties.Descendants().FirstOrDefault( el => el.Name.LocalName == "numId" ); | |||||
| var numIdValue = numIdNode.Attribute( DocX.w + "val" ).Value; | |||||
| var numIdNode = paragraphNumberPropertiesDescendants.FirstOrDefault( el => el.Name.LocalName == "numId" ); | |||||
| var numIdValue = ( numIdNode != null ) ? numIdNode.Attribute( DocX.w + "val" ).Value : null; | |||||
| //find num node in numbering | //find num node in numbering | ||||
| var numNodes = document._numbering.Descendants().Where( n => n.Name.LocalName == "num" ); | |||||
| var documentNumberingDescendants = document._numbering.Descendants(); | |||||
| var numNodes = documentNumberingDescendants.Where( n => n.Name.LocalName == "num" ); | |||||
| XElement numNode = numNodes.FirstOrDefault( node => node.Attribute( DocX.w + "numId" ).Value.Equals( numIdValue ) ); | XElement numNode = numNodes.FirstOrDefault( node => node.Attribute( DocX.w + "numId" ).Value.Equals( numIdValue ) ); | ||||
| if( numNode != null ) | if( numNode != null ) | ||||
| var abstractNumIdNode = numNode.Descendants().First( n => n.Name.LocalName == "abstractNumId" ); | var abstractNumIdNode = numNode.Descendants().First( n => n.Name.LocalName == "abstractNumId" ); | ||||
| var abstractNumNodeValue = abstractNumIdNode.Attribute( DocX.w + "val" ).Value; | var abstractNumNodeValue = abstractNumIdNode.Attribute( DocX.w + "val" ).Value; | ||||
| var abstractNumNodes = document._numbering.Descendants().Where( n => n.Name.LocalName == "abstractNum" ); | |||||
| var abstractNumNodes = documentNumberingDescendants.Where( n => n.Name.LocalName == "abstractNum" ); | |||||
| XElement abstractNumNode = abstractNumNodes.FirstOrDefault( node => node.Attribute( DocX.w + "abstractNumId" ).Value.Equals( abstractNumNodeValue ) ); | XElement abstractNumNode = abstractNumNodes.FirstOrDefault( node => node.Attribute( DocX.w + "abstractNumId" ).Value.Equals( abstractNumNodeValue ) ); | ||||
| //Find lvl node | //Find lvl node | ||||
| lvlNode = node; | lvlNode = node; | ||||
| break; | break; | ||||
| } | } | ||||
| else if( ilvlValue == null ) | |||||
| { | |||||
| var numStyleNode = node.Descendants().FirstOrDefault( n => n.Name.LocalName == "pStyle" ); | |||||
| if( ( numStyleNode != null) && numStyleNode.GetAttribute( DocX.w + "val" ).Equals( p.StyleName ) ) | |||||
| { | |||||
| lvlNode = node; | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | } | ||||
| var numFmtNode = lvlNode.Descendants().First( n => n.Name.LocalName == "numFmt" ); | |||||
| return numFmtNode.Attribute( DocX.w + "val" ).Value; | |||||
| if( lvlNode != null ) | |||||
| { | |||||
| var numFmtNode = lvlNode.Descendants().First( n => n.Name.LocalName == "numFmt" ); | |||||
| return numFmtNode.Attribute( DocX.w + "val" ).Value; | |||||
| } | |||||
| } | } | ||||
| return null; | return null; | ||||
| } | } | ||||
| internal static string GetListItemStartValue( List list, int level ) | |||||
| { | |||||
| var abstractNumElement = list.GetAbstractNum( list.NumId ); | |||||
| //Find lvl node | |||||
| var lvlNodes = abstractNumElement.Descendants().Where( n => n.Name.LocalName == "lvl" ); | |||||
| var lvlNode = lvlNodes.FirstOrDefault( n => n.GetAttribute( DocX.w + "ilvl" ).Equals( level.ToString() ) ); | |||||
| var startNode = lvlNode.Descendants().First( n => n.Name.LocalName == "start" ); | |||||
| return startNode.GetAttribute( DocX.w + "val" ); | |||||
| } | |||||
| internal static string GetListItemTextFormat( List list, int level ) | |||||
| { | |||||
| var abstractNumElement = list.GetAbstractNum( list.NumId ); | |||||
| //Find lvl node | |||||
| var lvlNodes = abstractNumElement.Descendants().Where( n => n.Name.LocalName == "lvl" ); | |||||
| var lvlNode = lvlNodes.FirstOrDefault( n => n.GetAttribute( DocX.w + "ilvl" ).Equals( level.ToString() ) ); | |||||
| var textFormatNode = lvlNode.Descendants().First( n => n.Name.LocalName == "lvlText" ); | |||||
| return textFormatNode.GetAttribute( DocX.w + "val" ); | |||||
| } | |||||
| internal static XElement GetListItemAlignment( List list, int level ) | |||||
| { | |||||
| var abstractNumElement = list.GetAbstractNum( list.NumId ); | |||||
| //Find lvl node | |||||
| var lvlNodes = abstractNumElement.Descendants().Where( n => n.Name.LocalName == "lvl" ); | |||||
| var lvlNode = lvlNodes.FirstOrDefault( n => n.GetAttribute( DocX.w + "ilvl" ).Equals( level.ToString() ) ); | |||||
| var pPr = lvlNode.Descendants().FirstOrDefault( n => n.Name.LocalName == "pPr" ); | |||||
| if( pPr != null ) | |||||
| { | |||||
| var ind = pPr.Descendants().FirstOrDefault( n => n.Name.LocalName == "ind" ); | |||||
| if( ind != null ) | |||||
| { | |||||
| return ind; | |||||
| } | |||||
| } | |||||
| return null; | |||||
| } | |||||
| } | } | ||||
| } | } |
| { | { | ||||
| get | get | ||||
| { | { | ||||
| if( type == 0 && id != String.Empty ) | |||||
| if( (type == 0) && !String.IsNullOrEmpty(id) ) | |||||
| { | { | ||||
| var r = this.PackagePart.GetRelationship( id ); | var r = this.PackagePart.GetRelationship( id ); | ||||
| return r.TargetUri; | return r.TargetUri; | ||||
| internal Hyperlink( DocX document, PackagePart mainPart, XElement i ) : base( document, i ) | internal Hyperlink( DocX document, PackagePart mainPart, XElement i ) : base( document, i ) | ||||
| { | { | ||||
| this.type = 0; | this.type = 0; | ||||
| this.id = i.Attribute( XName.Get( "id", DocX.r.NamespaceName ) ).Value; | |||||
| var idAttribute = i.Attribute( XName.Get( "id", DocX.r.NamespaceName ) ); | |||||
| if( idAttribute != null ) | |||||
| { | |||||
| this.id = idAttribute.Value; | |||||
| } | |||||
| StringBuilder sb = new StringBuilder(); | StringBuilder sb = new StringBuilder(); | ||||
| HelperFunctions.GetTextRecursive( i, ref sb ); | HelperFunctions.GetTextRecursive( i, ref sb ); | ||||
| try | try | ||||
| { | { | ||||
| int start = instrText.Value.IndexOf( "HYPERLINK \"" ) + "HYPERLINK \"".Length; | |||||
| int end = instrText.Value.IndexOf( "\"", start ); | |||||
| int start = instrText.Value.IndexOf( "HYPERLINK \"" ); | |||||
| if( start != -1 ) | |||||
| start += "HYPERLINK \"".Length; | |||||
| int end = instrText.Value.IndexOf( "\"", Math.Max( 0, start )); | |||||
| if( start != -1 && end != -1 ) | if( start != -1 && end != -1 ) | ||||
| { | { | ||||
| this.uri = new Uri( instrText.Value.Substring( start, end - start ), UriKind.Absolute ); | this.uri = new Uri( instrText.Value.Substring( start, end - start ), UriKind.Absolute ); |
| internal XElement GetAbstractNum( int numId ) | internal XElement GetAbstractNum( int numId ) | ||||
| { | { | ||||
| var num = Document._numbering.Descendants().First( d => d.Name.LocalName == "num" && d.GetAttribute( DocX.w + "numId" ).Equals( numId.ToString() ) ); | var num = Document._numbering.Descendants().First( d => d.Name.LocalName == "num" && d.GetAttribute( DocX.w + "numId" ).Equals( numId.ToString() ) ); | ||||
| var abstractNumId = num.Descendants().First( d => d.Name.LocalName == "abstractNumId" ); | |||||
| return Document._numbering.Descendants().First( d => d.Name.LocalName == "abstractNum" && d.GetAttribute( "abstractNumId" ).Equals( abstractNumId.Value ) ); | |||||
| var abstractNumId = num.Descendants().First( d => d.Name.LocalName == "abstractNumId" ).GetAttribute( DocX.w + "val" ); | |||||
| return Document._numbering.Descendants().First( d => d.Name.LocalName == "abstractNum" && d.GetAttribute( DocX.w + "abstractNumId" ).Equals( abstractNumId ) ); | |||||
| } | } | ||||
| #endregion | #endregion |
| { | { | ||||
| #region Private Members | #region Private Members | ||||
| private static readonly Mutex _mutex = new Mutex( false ); | |||||
| private static readonly object lockObject = new object(); | |||||
| private readonly Stream _stream; | private readonly Stream _stream; | ||||
| #endregion | #endregion | ||||
| public override void Write( byte[] buffer, int offset, int count ) | public override void Write( byte[] buffer, int offset, int count ) | ||||
| { | { | ||||
| _mutex.WaitOne( Timeout.Infinite, false ); | |||||
| _stream.Write( buffer, offset, count ); | |||||
| _mutex.ReleaseMutex(); | |||||
| lock(lockObject) | |||||
| { | |||||
| _stream.Write( buffer, offset, count ); | |||||
| } | |||||
| } | } | ||||
| public override void Flush() | public override void Flush() | ||||
| { | { | ||||
| _mutex.WaitOne( Timeout.Infinite, false ); | |||||
| _stream.Flush(); | |||||
| _mutex.ReleaseMutex(); | |||||
| lock(lockObject) | |||||
| { | |||||
| _stream.Flush(); | |||||
| } | |||||
| } | } | ||||
| public override void Close() | public override void Close() |
| internal int _startIndex, _endIndex; | internal int _startIndex, _endIndex; | ||||
| internal List<XElement> _styles = new List<XElement>(); | internal List<XElement> _styles = new List<XElement>(); | ||||
| internal const float DefaultLineSpacing = 1.1f * 20.0f; | |||||
| #endregion | #endregion | ||||
| #region Private Members | #region Private Members | ||||
| { | { | ||||
| get; set; | get; set; | ||||
| } | } | ||||
| private bool? IsListItemBacker | private bool? IsListItemBacker | ||||
| { | { | ||||
| get; set; | get; set; | ||||
| } | } | ||||
| private int? IndentLevelBacker | private int? IndentLevelBacker | ||||
| { | { | ||||
| get; set; | get; set; | ||||
| { | { | ||||
| get | get | ||||
| { | { | ||||
| if( Xml == null ) | |||||
| { | |||||
| return new List<Picture>(); | |||||
| } | |||||
| var pictures = this.GetPictures( "drawing", "blip", "embed" ); | var pictures = this.GetPictures( "drawing", "blip", "embed" ); | ||||
| var shapes = this.GetPictures( "pict", "imagedata", "id" ); | var shapes = this.GetPictures( "pict", "imagedata", "id" ); | ||||
| XAttribute firstLine = ind.Attribute( XName.Get( "firstLine", DocX.w.NamespaceName ) ); | XAttribute firstLine = ind.Attribute( XName.Get( "firstLine", DocX.w.NamespaceName ) ); | ||||
| if( firstLine != null ) | if( firstLine != null ) | ||||
| return float.Parse( firstLine.Value ); | |||||
| return float.Parse( firstLine.Value ) / 570f; | |||||
| return 0.0f; | return 0.0f; | ||||
| } | } | ||||
| firstLine.Remove(); | firstLine.Remove(); | ||||
| } | } | ||||
| var indentation = ( ( indentationHanging / 0.1 ) * 57 ).ToString(); | |||||
| var indentationValue = ( ( indentationHanging / 0.1 ) * 57 ); | |||||
| var indentation = indentationValue.ToString(); | |||||
| var hanging = ind.Attribute( XName.Get( "hanging", DocX.w.NamespaceName ) ); | var hanging = ind.Attribute( XName.Get( "hanging", DocX.w.NamespaceName ) ); | ||||
| if( hanging != null ) | if( hanging != null ) | ||||
| { | { | ||||
| { | { | ||||
| ind.Add( new XAttribute( XName.Get( "hanging", DocX.w.NamespaceName ), indentation ) ); | ind.Add( new XAttribute( XName.Get( "hanging", DocX.w.NamespaceName ), indentation ) ); | ||||
| } | } | ||||
| IndentationBefore = indentationHanging; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| GetOrCreate_pPr(); | GetOrCreate_pPr(); | ||||
| var ind = GetOrCreate_pPr_ind(); | var ind = GetOrCreate_pPr_ind(); | ||||
| var indentation = ( ( indentationBefore / 0.1 ) * 57 ).ToString(CultureInfo.GetCultureInfo("en-GB")); | |||||
| var indentation = ( ( indentationBefore / 0.1 ) * 57 ).ToString(); | |||||
| var left = ind.Attribute( XName.Get( "left", DocX.w.NamespaceName ) ); | var left = ind.Attribute( XName.Get( "left", DocX.w.NamespaceName ) ); | ||||
| if( left != null ) | if( left != null ) | ||||
| var right = ind.Attribute( XName.Get( "right", DocX.w.NamespaceName ) ); | var right = ind.Attribute( XName.Get( "right", DocX.w.NamespaceName ) ); | ||||
| if( right != null ) | if( right != null ) | ||||
| return float.Parse( right.Value ); | |||||
| return float.Parse( right.Value ) / 570f; | |||||
| return 0.0f; | return 0.0f; | ||||
| } | } | ||||
| XElement spacing = pPr.Element( XName.Get( "spacing", DocX.w.NamespaceName ) ); | XElement spacing = pPr.Element( XName.Get( "spacing", DocX.w.NamespaceName ) ); | ||||
| if( spacing != null ) | if( spacing != null ) | ||||
| { | |||||
| { | |||||
| XAttribute line = spacing.Attribute( XName.Get( "line", DocX.w.NamespaceName ) ); | XAttribute line = spacing.Attribute( XName.Get( "line", DocX.w.NamespaceName ) ); | ||||
| if( line != null ) | if( line != null ) | ||||
| { | { | ||||
| } | } | ||||
| } | } | ||||
| return 1.1f * 20.0f; | |||||
| return Paragraph.DefaultLineSpacing; | |||||
| } | } | ||||
| set | set | ||||
| } | } | ||||
| } | } | ||||
| return 10.0f; | |||||
| return 0.0f; | |||||
| } | } | ||||
| { | { | ||||
| if( !IsListItem ) | if( !IsListItem ) | ||||
| return null; | return null; | ||||
| return IndentLevelBacker ?? ( IndentLevelBacker = int.Parse( ParagraphNumberProperties.Descendants().First( el => el.Name.LocalName == "ilvl" ).GetAttribute( DocX.w + "val" ) ) ); | |||||
| if( IndentLevelBacker != null ) | |||||
| return IndentLevelBacker; | |||||
| var ilvl = ParagraphNumberProperties.Descendants().FirstOrDefault( el => el.Name.LocalName == "ilvl" ); | |||||
| return IndentLevelBacker = ( ilvl != null ) ? int.Parse( ilvl.GetAttribute( DocX.w + "val" ) ) : 0; | |||||
| } | } | ||||
| } | } | ||||
| return base.InsertTableAfterSelf( rowCount, columnCount ); | return base.InsertTableAfterSelf( rowCount, columnCount ); | ||||
| } | } | ||||
| /// <summary> | |||||
| /// Replaces an existing Picture with a new Picture. | |||||
| /// </summary> | |||||
| /// <param name="toBeReplaced">The picture object to be replaced.</param> | |||||
| /// <param name="replaceWith">The picture object that should be inserted instead of <paramref name="toBeReplaced"/>.</param> | |||||
| /// <returns>The new <see cref="Picture"/> object that replaces the old one.</returns> | |||||
| public Picture ReplacePicture( Picture toBeReplaced, Picture replaceWith ) | |||||
| { | |||||
| var document = this.Document; | |||||
| var newDocPrId = document.GetNextFreeDocPrId(); | |||||
| var xml = XElement.Parse( toBeReplaced.Xml.ToString() ); | |||||
| foreach( var element in xml.Descendants( XName.Get( "docPr", DocX.wp.NamespaceName ) ) ) | |||||
| element.SetAttributeValue( XName.Get( "id" ), newDocPrId ); | |||||
| foreach( var element in xml.Descendants( XName.Get( "blip", DocX.a.NamespaceName ) ) ) | |||||
| element.SetAttributeValue( XName.Get( "embed", DocX.r.NamespaceName ), replaceWith.Id ); | |||||
| var replacePicture = new Picture( document, xml, new Image( document, this.PackagePart.GetRelationship( replaceWith.Id ) ) ); | |||||
| this.AppendPicture( replacePicture ); | |||||
| toBeReplaced.Remove(); | |||||
| return replacePicture; | |||||
| } | |||||
| /// <summary> | /// <summary> | ||||
| /// Insert a Paragraph before this Paragraph, this Paragraph may have come from the same or another document. | /// Insert a Paragraph before this Paragraph, this Paragraph may have come from the same or another document. | ||||
| /// </summary> | /// </summary> | ||||
| XElement h_xml; | XElement h_xml; | ||||
| if( index == 0 ) | if( index == 0 ) | ||||
| { | { | ||||
| // Add this hyperlink as the last element. | |||||
| // Add this hyperlink as the first element. | |||||
| Xml.AddFirst( h.Xml ); | Xml.AddFirst( h.Xml ); | ||||
| // Extract the picture back out of the DOM. | // Extract the picture back out of the DOM. | ||||
| h_xml.SetAttributeValue( DocX.r + "id", Id ); | h_xml.SetAttributeValue( DocX.r + "id", Id ); | ||||
| } | } | ||||
| this._runs = Xml.Elements().Last().Elements( XName.Get( "r", DocX.w.NamespaceName ) ).ToList(); | |||||
| return this; | return this; | ||||
| } | } | ||||
| // return newPicture; | // return newPicture; | ||||
| //} | //} | ||||
| /// <summary> | |||||
| /// Insert a Picture at the end of this paragraph. | |||||
| /// </summary> | |||||
| /// <param name="description">A string to describe this Picture.</param> | |||||
| /// <param name="imageID">The unique id that identifies the Image this Picture represents.</param> | |||||
| /// <param name="name">The name of this image.</param> | |||||
| /// <returns>A Picture.</returns> | |||||
| /// <example> | |||||
| /// <code> | |||||
| /// // Create a document using a relative filename. | |||||
| /// using (DocX document = DocX.Create(@"Test.docx")) | |||||
| /// { | |||||
| /// // Add a new Paragraph to this document. | |||||
| /// Paragraph p = document.InsertParagraph("Here is Picture 1", false); | |||||
| /// | |||||
| /// // Add an Image to this document. | |||||
| /// Xceed.Words.NET.Image img = document.AddImage(@"Image.jpg"); | |||||
| /// | |||||
| /// // Insert pic at the end of Paragraph p. | |||||
| /// Picture pic = p.InsertPicture(img.Id, "Photo 31415", "A pie I baked."); | |||||
| /// | |||||
| /// // Rotate the Picture clockwise by 30 degrees. | |||||
| /// pic.Rotation = 30; | |||||
| /// | |||||
| /// // Resize the Picture. | |||||
| /// pic.Width = 400; | |||||
| /// pic.Height = 300; | |||||
| /// | |||||
| /// // Set the shape of this Picture to be a cube. | |||||
| /// pic.SetPictureShape(BasicShapes.cube); | |||||
| /// | |||||
| /// // Flip the Picture Horizontally. | |||||
| /// pic.FlipHorizontal = true; | |||||
| /// | |||||
| /// // Save all changes made to this document. | |||||
| /// document.Save(); | |||||
| /// }// Release this document from memory. | |||||
| /// </code> | |||||
| /// </example> | |||||
| /// Removed to simplify the API. | |||||
| // <summary> | |||||
| // Insert a Picture at the end of this paragraph. | |||||
| // </summary> | |||||
| // <param name="description">A string to describe this Picture.</param> | |||||
| // <param name="imageID">The unique id that identifies the Image this Picture represents.</param> | |||||
| // <param name="name">The name of this image.</param> | |||||
| // <returns>A Picture.</returns> | |||||
| // <example> | |||||
| // <code> | |||||
| // // Create a document using a relative filename. | |||||
| // using (DocX document = DocX.Create(@"Test.docx")) | |||||
| // { | |||||
| // // Add a new Paragraph to this document. | |||||
| // Paragraph p = document.InsertParagraph("Here is Picture 1", false); | |||||
| // | |||||
| // // Add an Image to this document. | |||||
| // Xceed.Words.NET.Image img = document.AddImage(@"Image.jpg"); | |||||
| // | |||||
| // // Insert pic at the end of Paragraph p. | |||||
| // Picture pic = p.InsertPicture(img.Id, "Photo 31415", "A pie I baked."); | |||||
| // | |||||
| // // Rotate the Picture clockwise by 30 degrees. | |||||
| // pic.Rotation = 30; | |||||
| // | |||||
| // // Resize the Picture. | |||||
| // pic.Width = 400; | |||||
| // pic.Height = 300; | |||||
| // | |||||
| // // Set the shape of this Picture to be a cube. | |||||
| // pic.SetPictureShape(BasicShapes.cube); | |||||
| // | |||||
| // // Flip the Picture Horizontally. | |||||
| // pic.FlipHorizontal = true; | |||||
| // | |||||
| // // Save all changes made to this document. | |||||
| // document.Save(); | |||||
| // }// Release this document from memory. | |||||
| // </code> | |||||
| // </example> | |||||
| // Removed to simplify the API. | |||||
| //public Picture InsertPicture(string imageID, string name, string description) | //public Picture InsertPicture(string imageID, string name, string description) | ||||
| //{ | //{ | ||||
| // Picture p = CreatePicture(Document, imageID, name, description); | // Picture p = CreatePicture(Document, imageID, name, description); | ||||
| // return p; | // return p; | ||||
| //} | //} | ||||
| /// <summary> | |||||
| /// Insert a Picture into this Paragraph at a specified index. | |||||
| /// </summary> | |||||
| /// <param name="description">A string to describe this Picture.</param> | |||||
| /// <param name="imageID">The unique id that identifies the Image this Picture represents.</param> | |||||
| /// <param name="name">The name of this image.</param> | |||||
| /// <param name="index">The index to insert this Picture at.</param> | |||||
| /// <returns>A Picture.</returns> | |||||
| /// <example> | |||||
| /// <code> | |||||
| /// // Create a document using a relative filename. | |||||
| /// using (DocX document = DocX.Create(@"Test.docx")) | |||||
| /// { | |||||
| /// // Add a new Paragraph to this document. | |||||
| /// Paragraph p = document.InsertParagraph("Here is Picture 1", false); | |||||
| /// | |||||
| /// // Add an Image to this document. | |||||
| /// Xceed.Words.NET.Image img = document.AddImage(@"Image.jpg"); | |||||
| /// | |||||
| /// // Insert pic at the start of Paragraph p. | |||||
| /// Picture pic = p.InsertPicture(0, img.Id, "Photo 31415", "A pie I baked."); | |||||
| /// | |||||
| /// // Rotate the Picture clockwise by 30 degrees. | |||||
| /// pic.Rotation = 30; | |||||
| /// | |||||
| /// // Resize the Picture. | |||||
| /// pic.Width = 400; | |||||
| /// pic.Height = 300; | |||||
| /// | |||||
| /// // Set the shape of this Picture to be a cube. | |||||
| /// pic.SetPictureShape(BasicShapes.cube); | |||||
| /// | |||||
| /// // Flip the Picture Horizontally. | |||||
| /// pic.FlipHorizontal = true; | |||||
| /// | |||||
| /// // Save all changes made to this document. | |||||
| /// document.Save(); | |||||
| /// }// Release this document from memory. | |||||
| /// </code> | |||||
| /// </example> | |||||
| /// Removed to simplify API. | |||||
| // <summary> | |||||
| // Insert a Picture into this Paragraph at a specified index. | |||||
| // </summary> | |||||
| // <param name="description">A string to describe this Picture.</param> | |||||
| // <param name="imageID">The unique id that identifies the Image this Picture represents.</param> | |||||
| // <param name="name">The name of this image.</param> | |||||
| // <param name="index">The index to insert this Picture at.</param> | |||||
| // <returns>A Picture.</returns> | |||||
| // <example> | |||||
| // <code> | |||||
| // // Create a document using a relative filename. | |||||
| // using (DocX document = DocX.Create(@"Test.docx")) | |||||
| // { | |||||
| // // Add a new Paragraph to this document. | |||||
| // Paragraph p = document.InsertParagraph("Here is Picture 1", false); | |||||
| // | |||||
| // // Add an Image to this document. | |||||
| // Xceed.Words.NET.Image img = document.AddImage(@"Image.jpg"); | |||||
| // | |||||
| // // Insert pic at the start of Paragraph p. | |||||
| // Picture pic = p.InsertPicture(0, img.Id, "Photo 31415", "A pie I baked."); | |||||
| // | |||||
| // // Rotate the Picture clockwise by 30 degrees. | |||||
| // pic.Rotation = 30; | |||||
| // | |||||
| // // Resize the Picture. | |||||
| // pic.Width = 400; | |||||
| // pic.Height = 300; | |||||
| // | |||||
| // // Set the shape of this Picture to be a cube. | |||||
| // pic.SetPictureShape(BasicShapes.cube); | |||||
| // | |||||
| // // Flip the Picture Horizontally. | |||||
| // pic.FlipHorizontal = true; | |||||
| // | |||||
| // // Save all changes made to this document. | |||||
| // document.Save(); | |||||
| // }// Release this document from memory. | |||||
| // </code> | |||||
| // </example> | |||||
| // Removed to simplify API. | |||||
| //public Picture InsertPicture(int index, string imageID, string name, string description) | //public Picture InsertPicture(int index, string imageID, string name, string description) | ||||
| //{ | //{ | ||||
| // Picture picture = CreatePicture(Document, imageID, name, description); | // Picture picture = CreatePicture(Document, imageID, name, description); | ||||
| /// </code> | /// </code> | ||||
| /// </example> | /// </example> | ||||
| /// <seealso cref="Paragraph.RemoveText(int, bool)"/> | /// <seealso cref="Paragraph.RemoveText(int, bool)"/> | ||||
| /// <seealso cref="Paragraph.RemoveText(int, int, bool)"/> | |||||
| /// <seealso cref="Paragraph.RemoveText(int, int, bool, bool)"/> | |||||
| /// <param name="value">The System.String to insert.</param> | /// <param name="value">The System.String to insert.</param> | ||||
| /// <param name="trackChanges">Flag this insert as a change.</param> | /// <param name="trackChanges">Flag this insert as a change.</param> | ||||
| /// <param name="formatting">The text formatting.</param> | /// <param name="formatting">The text formatting.</param> | ||||
| public void InsertText( string value, bool trackChanges = false, Formatting formatting = null ) | public void InsertText( string value, bool trackChanges = false, Formatting formatting = null ) | ||||
| { | { | ||||
| // Default values for optional parameters must be compile time constants. | |||||
| // Would have like to write 'public void InsertText(string value, bool trackChanges = false, Formatting formatting = new Formatting()) | |||||
| if( formatting == null ) | |||||
| { | |||||
| formatting = new Formatting(); | |||||
| } | |||||
| var newRuns = HelperFunctions.FormatInput( value, formatting.Xml ); | |||||
| Xml.Add( newRuns ); | |||||
| HelperFunctions.RenumberIDs( Document ); | |||||
| this.InsertText( this.Text.Length, value, trackChanges, formatting ); | |||||
| } | } | ||||
| /// <summary> | /// <summary> | ||||
| /// </code> | /// </code> | ||||
| /// </example> | /// </example> | ||||
| /// <seealso cref="Paragraph.RemoveText(int, bool)"/> | /// <seealso cref="Paragraph.RemoveText(int, bool)"/> | ||||
| /// <seealso cref="Paragraph.RemoveText(int, int, bool)"/> | |||||
| /// <seealso cref="Paragraph.RemoveText(int, int, bool, bool)"/> | |||||
| /// <param name="index">The index position of the insertion.</param> | /// <param name="index">The index position of the insertion.</param> | ||||
| /// <param name="value">The System.String to insert.</param> | /// <param name="value">The System.String to insert.</param> | ||||
| /// <param name="trackChanges">Flag this insert as a change.</param> | /// <param name="trackChanges">Flag this insert as a change.</param> | ||||
| { | { | ||||
| insert = CreateEdit( EditType.ins, insert_datetime, newRuns ); | insert = CreateEdit( EditType.ins, insert_datetime, newRuns ); | ||||
| } | } | ||||
| // Special case to deal with Page Number elements. | |||||
| //if (parentElement.Name.LocalName.Equals("fldSimple")) | |||||
| // parentElement.AddBeforeSelf(insert); | |||||
| else | |||||
| { | |||||
| // Split this run at the point you want to insert | |||||
| var splitRun = Run.SplitRun( run, index ); | |||||
| // Replace the origional run | |||||
| run.Xml.ReplaceWith | |||||
| ( | |||||
| splitRun[ 0 ], | |||||
| insert, | |||||
| splitRun[ 1 ] | |||||
| ); | |||||
| } | |||||
| // Split this run at the point you want to insert | |||||
| var splitRun = Run.SplitRun( run, index ); | |||||
| // Replace the origional run | |||||
| run.Xml.ReplaceWith | |||||
| ( | |||||
| splitRun[ 0 ], | |||||
| insert, | |||||
| splitRun[ 1 ] | |||||
| ); | |||||
| break; | break; | ||||
| } | } | ||||
| if( format.Highlight.HasValue ) | if( format.Highlight.HasValue ) | ||||
| Highlight( format.Highlight.Value ); | Highlight( format.Highlight.Value ); | ||||
| // Shading | |||||
| if( format.Shading.HasValue ) | |||||
| Shading( format.Shading.Value ); | |||||
| // Italic | // Italic | ||||
| if( format.Italic.HasValue && format.Italic.Value ) | if( format.Italic.HasValue && format.Italic.Value ) | ||||
| Italic(); | Italic(); | ||||
| return this; | return this; | ||||
| } | } | ||||
| /// <summary> | |||||
| /// Add a new TabStopPosition in the current paragraph. | |||||
| /// </summary> | |||||
| /// <param name="alignment">Specifies the alignment of the Tab stop.</param> | |||||
| /// <param name="position">Specifies the horizontal position of the tab stop.</param> | |||||
| /// <param name="leader">Specifies the character used to fill in the space created by a tab.</param> | |||||
| /// <returns>The modified Paragraph.</returns> | |||||
| public Paragraph InsertTabStopPosition( Alignment alignment, float position, TabStopPositionLeader leader = TabStopPositionLeader.none ) | |||||
| { | |||||
| var pPr = GetOrCreate_pPr(); | |||||
| var tabs = pPr.Element( XName.Get( "tabs", DocX.w.NamespaceName ) ); | |||||
| if( tabs == null ) | |||||
| { | |||||
| tabs = new XElement( XName.Get( "tabs", DocX.w.NamespaceName ) ); | |||||
| pPr.Add( tabs ); | |||||
| } | |||||
| var newTab = new XElement( XName.Get( "tab", DocX.w.NamespaceName ) ); | |||||
| // Alignement | |||||
| var alignmentString = string.Empty; | |||||
| switch( alignment ) | |||||
| { | |||||
| case Alignment.left: | |||||
| alignmentString = "left"; | |||||
| break; | |||||
| case Alignment.right: | |||||
| alignmentString = "right"; | |||||
| break; | |||||
| case Alignment.center: | |||||
| alignmentString = "center"; | |||||
| break; | |||||
| default: | |||||
| throw new ArgumentException( "alignment", "Value must be left, right or center." ); | |||||
| } | |||||
| newTab.SetAttributeValue( XName.Get( "val", DocX.w.NamespaceName ), alignmentString ); | |||||
| // Position | |||||
| var posValue = position * 20.0f; | |||||
| newTab.SetAttributeValue( XName.Get( "pos", DocX.w.NamespaceName ), posValue.ToString() ); | |||||
| //Leader | |||||
| var leaderString = string.Empty; | |||||
| switch( leader ) | |||||
| { | |||||
| case TabStopPositionLeader.none: | |||||
| leaderString = "none"; | |||||
| break; | |||||
| case TabStopPositionLeader.dot: | |||||
| leaderString = "dot"; | |||||
| break; | |||||
| case TabStopPositionLeader.underscore: | |||||
| leaderString = "underscore"; | |||||
| break; | |||||
| case TabStopPositionLeader.hyphen: | |||||
| leaderString = "hyphen"; | |||||
| break; | |||||
| default: | |||||
| throw new ArgumentException( "leader", "Unknown leader character." ); | |||||
| } | |||||
| newTab.SetAttributeValue( XName.Get( "leader", DocX.w.NamespaceName ), leaderString ); | |||||
| tabs.Add( newTab ); | |||||
| return this; | |||||
| } | |||||
| /// <summary> | /// <summary> | ||||
| /// Append text on a new line to this Paragraph. | /// Append text on a new line to this Paragraph. | ||||
| /// </summary> | /// </summary> | ||||
| return this; | return this; | ||||
| } | } | ||||
| public Paragraph Shading( Color shading, ShadingType shadingType = ShadingType.Text ) | |||||
| { | |||||
| // Add to run | |||||
| if( shadingType == ShadingType.Text ) | |||||
| { | |||||
| this.ApplyTextFormattingProperty( XName.Get( "shd", DocX.w.NamespaceName ), string.Empty, new XAttribute( XName.Get( "fill", DocX.w.NamespaceName ), shading.ToHex() ) ); | |||||
| } | |||||
| // Add to paragraph | |||||
| else | |||||
| { | |||||
| var pPr = GetOrCreate_pPr(); | |||||
| var shd = pPr.Element( XName.Get( "shd", DocX.w.NamespaceName ) ); | |||||
| if( shd == null ) | |||||
| { | |||||
| shd = new XElement( XName.Get( "shd", DocX.w.NamespaceName ) ); | |||||
| pPr.Add( shd ); | |||||
| } | |||||
| var fillAttribute = shd.Attribute( XName.Get( "fill", DocX.w.NamespaceName ) ); | |||||
| if( fillAttribute == null ) | |||||
| { | |||||
| shd.SetAttributeValue( XName.Get( "fill", DocX.w.NamespaceName ), shading.ToHex() ); | |||||
| } | |||||
| else | |||||
| { | |||||
| fillAttribute.SetValue( shading.ToHex() ); | |||||
| } | |||||
| } | |||||
| return this; | |||||
| } | |||||
| /// <summary> | /// <summary> | ||||
| /// For use with Append() and AppendLine() | /// For use with Append() and AppendLine() | ||||
| /// </summary> | /// </summary> | ||||
| /// </summary> | /// </summary> | ||||
| /// <param name="cp">The custom property to display.</param> | /// <param name="cp">The custom property to display.</param> | ||||
| /// <param name="f">The formatting to use for this text.</param> | /// <param name="f">The formatting to use for this text.</param> | ||||
| /// <param name="trackChanges"></param> | |||||
| /// <example> | /// <example> | ||||
| /// Create, add and display a custom property in a document. | /// Create, add and display a custom property in a document. | ||||
| /// <code> | /// <code> | ||||
| /// Insert a field of type document property, this field will display the custom property cp, at the end of this paragraph. | /// Insert a field of type document property, this field will display the custom property cp, at the end of this paragraph. | ||||
| /// </summary> | /// </summary> | ||||
| /// <param name="cp">The custom property to display.</param> | /// <param name="cp">The custom property to display.</param> | ||||
| /// <param name="trackChanges"></param> | |||||
| /// <param name="trackChanges">if the changes are tracked.</param> | |||||
| /// <param name="f">The formatting to use for this text.</param> | /// <param name="f">The formatting to use for this text.</param> | ||||
| /// <example> | /// <example> | ||||
| /// Create, add and display a custom property in a document. | /// Create, add and display a custom property in a document. | ||||
| /// <param name="index">The position to begin deleting characters.</param> | /// <param name="index">The position to begin deleting characters.</param> | ||||
| /// <param name="count">The number of characters to delete</param> | /// <param name="count">The number of characters to delete</param> | ||||
| /// <param name="trackChanges">Track changes</param> | /// <param name="trackChanges">Track changes</param> | ||||
| public void RemoveText( int index, int count, bool trackChanges = false ) | |||||
| /// <param name="removeEmptyParagraph">Remove empty paragraph</param> | |||||
| public void RemoveText( int index, int count, bool trackChanges = false, bool removeEmptyParagraph = true ) | |||||
| { | { | ||||
| // Timestamp to mark the start of insert | // Timestamp to mark the start of insert | ||||
| var now = DateTime.Now; | var now = DateTime.Now; | ||||
| var min = Math.Min( count - processed, run.Xml.ElementsAfterSelf().Sum( e => GetElementTextLength( e ) ) ); | var min = Math.Min( count - processed, run.Xml.ElementsAfterSelf().Sum( e => GetElementTextLength( e ) ) ); | ||||
| var splitEditAfter = this.SplitEdit( parentElement, index + min, EditType.del ); | var splitEditAfter = this.SplitEdit( parentElement, index + min, EditType.del ); | ||||
| var temp = this.SplitEdit( splitEditBefore[ 1 ], index + min, EditType.del )[ 0 ]; | |||||
| var temp = this.SplitEdit( splitEditBefore[ 1 ], index + min, EditType.del )[ 1 ]; | |||||
| var middle = Paragraph.CreateEdit( EditType.del, remove_datetime, temp.Elements() ); | var middle = Paragraph.CreateEdit( EditType.del, remove_datetime, temp.Elements() ); | ||||
| processed += Paragraph.GetElementTextLength( middle as XElement ); | processed += Paragraph.GetElementTextLength( middle as XElement ); | ||||
| middle = null; | middle = null; | ||||
| } | } | ||||
| parentElement.ReplaceWith( splitEditBefore[ 0 ], middle, splitEditAfter[ 1 ] ); | |||||
| parentElement.ReplaceWith( splitEditBefore[ 0 ], middle, splitEditAfter[ 0 ] ); | |||||
| processed += Paragraph.GetElementTextLength( middle as XElement ); | processed += Paragraph.GetElementTextLength( middle as XElement ); | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| // If after this remove the parent element is empty, remove it. | |||||
| if( Paragraph.GetElementTextLength( parentElement ) == 0 ) | |||||
| // In some cases, removing an empty paragraph is allowed | |||||
| var canRemove = removeEmptyParagraph && GetElementTextLength( parentElement ) == 0; | |||||
| if( parentElement.Parent != null ) | |||||
| { | { | ||||
| if( ( parentElement.Parent != null ) && ( parentElement.Parent.Name.LocalName != "tc" ) ) | |||||
| { | |||||
| // Need to make sure there is no drawing element within the parent element. | |||||
| // Picture elements contain no text length but they are still content. | |||||
| if( parentElement.Descendants( XName.Get( "drawing", DocX.w.NamespaceName ) ).Count() == 0 ) | |||||
| { | |||||
| parentElement.Remove(); | |||||
| } | |||||
| } | |||||
| // Need to make sure there is another paragraph in the parent cell | |||||
| canRemove &= parentElement.Parent.Name.LocalName == "tc" && parentElement.Parent.Elements( XName.Get( "p", DocX.w.NamespaceName ) ).Count() > 1; | |||||
| // Need to make sure there is no drawing element within the parent element. | |||||
| // Picture elements contain no text length but they are still content. | |||||
| canRemove &= parentElement.Descendants( XName.Get( "drawing", DocX.w.NamespaceName ) ).Count() == 0; | |||||
| if( canRemove ) | |||||
| parentElement.Remove(); | |||||
| } | } | ||||
| } | } | ||||
| while( processed < count ); | while( processed < count ); | ||||
| /// }// Release this document from memory. | /// }// Release this document from memory. | ||||
| /// </code> | /// </code> | ||||
| /// </example> | /// </example> | ||||
| /// <seealso cref="Paragraph.RemoveText(int, int, bool)"/> | |||||
| /// <seealso cref="Paragraph.RemoveText(int, int, bool, bool)"/> | |||||
| /// <seealso cref="Paragraph.RemoveText(int, bool)"/> | /// <seealso cref="Paragraph.RemoveText(int, bool)"/> | ||||
| /// <seealso cref="Paragraph.InsertText(int, string, bool, Formatting)"/> | /// <seealso cref="Paragraph.InsertText(int, string, bool, Formatting)"/> | ||||
| /// <seealso cref="Paragraph.InsertText(string, bool, Formatting)"/> | /// <seealso cref="Paragraph.InsertText(string, bool, Formatting)"/> | ||||
| /// <param name="fo">How should formatting be matched?</param> | /// <param name="fo">How should formatting be matched?</param> | ||||
| /// <param name="escapeRegEx">True if the oldValue needs to be escaped, otherwise false. If it represents a valid RegEx pattern this should be false.</param> | /// <param name="escapeRegEx">True if the oldValue needs to be escaped, otherwise false. If it represents a valid RegEx pattern this should be false.</param> | ||||
| /// <param name="useRegExSubstitutions">True if RegEx-like replace should be performed, i.e. if newValue contains RegEx substitutions. Does not perform named-group substitutions (only numbered groups).</param> | /// <param name="useRegExSubstitutions">True if RegEx-like replace should be performed, i.e. if newValue contains RegEx substitutions. Does not perform named-group substitutions (only numbered groups).</param> | ||||
| /// <param name="removeEmptyParagraph">Remove empty paragraph</param> | |||||
| public void ReplaceText( string searchValue, | public void ReplaceText( string searchValue, | ||||
| string newValue, | string newValue, | ||||
| bool trackChanges = false, | bool trackChanges = false, | ||||
| Formatting matchFormatting = null, | Formatting matchFormatting = null, | ||||
| MatchFormattingOptions fo = MatchFormattingOptions.SubsetMatch, | MatchFormattingOptions fo = MatchFormattingOptions.SubsetMatch, | ||||
| bool escapeRegEx = true, | bool escapeRegEx = true, | ||||
| bool useRegExSubstitutions = false ) | |||||
| bool useRegExSubstitutions = false, | |||||
| bool removeEmptyParagraph = true ) | |||||
| { | { | ||||
| var mc = Regex.Matches( this.Text, escapeRegEx ? Regex.Escape( searchValue ) : searchValue, options ); | var mc = Regex.Matches( this.Text, escapeRegEx ? Regex.Escape( searchValue ) : searchValue, options ); | ||||
| } | } | ||||
| if( m.Length > 0 ) | if( m.Length > 0 ) | ||||
| { | { | ||||
| this.RemoveText( m.Index, m.Length, trackChanges ); | |||||
| this.RemoveText( m.Index, m.Length, trackChanges, removeEmptyParagraph ); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| public void ReplaceText( string findPattern, Func<string, string> regexMatchHandler, bool trackChanges = false, RegexOptions options = RegexOptions.None, Formatting newFormatting = null, Formatting matchFormatting = null, MatchFormattingOptions fo = MatchFormattingOptions.SubsetMatch ) | |||||
| public void ReplaceText( string findPattern, Func<string, string> regexMatchHandler, bool trackChanges = false, RegexOptions options = RegexOptions.None, Formatting newFormatting = null, Formatting matchFormatting = null, MatchFormattingOptions fo = MatchFormattingOptions.SubsetMatch, bool removeEmptyParagraph = true ) | |||||
| { | { | ||||
| var matchCol = Regex.Matches( this.Text, findPattern, options ); | var matchCol = Regex.Matches( this.Text, findPattern, options ); | ||||
| var reversedMatchCol = matchCol.Cast<Match>().Reverse(); | var reversedMatchCol = matchCol.Cast<Match>().Reverse(); | ||||
| { | { | ||||
| var newValue = regexMatchHandler.Invoke( match.Groups[ 1 ].Value ); | var newValue = regexMatchHandler.Invoke( match.Groups[ 1 ].Value ); | ||||
| this.InsertText( match.Index + match.Value.Length, newValue, trackChanges, newFormatting ); | this.InsertText( match.Index + match.Value.Length, newValue, trackChanges, newFormatting ); | ||||
| this.RemoveText( match.Index, match.Value.Length, trackChanges ); | |||||
| this.RemoveText( match.Index, match.Value.Length, trackChanges, removeEmptyParagraph ); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| tXElement.Value = text; | tXElement.Value = text; | ||||
| } | } | ||||
| public void InsertHorizontalLine( string lineType = "single", int size = 6, int space = 1, string color = "auto" ) | |||||
| public void InsertHorizontalLine( HorizontalBorderPosition position = HorizontalBorderPosition.bottom, string lineType = "single", int size = 6, int space = 1, string color = "auto" ) | |||||
| { | { | ||||
| var pBrXName = XName.Get( "pBdr", DocX.w.NamespaceName ); | var pBrXName = XName.Get( "pBdr", DocX.w.NamespaceName ); | ||||
| var bottomXName = XName.Get( "bottom", DocX.w.NamespaceName ); | |||||
| var borderPositionXName = ( position == HorizontalBorderPosition.bottom) ? XName.Get( "bottom", DocX.w.NamespaceName ) : XName.Get( "top", DocX.w.NamespaceName ); | |||||
| var pPr = this.GetOrCreate_pPr(); | var pPr = this.GetOrCreate_pPr(); | ||||
| var pBdr = pPr.Element( pBrXName ); | var pBdr = pPr.Element( pBrXName ); | ||||
| pBdr = pPr.Element( pBrXName ); | pBdr = pPr.Element( pBrXName ); | ||||
| //Add bottom | //Add bottom | ||||
| pBdr.Add( new XElement( bottomXName ) ); | |||||
| var bottom = pBdr.Element( bottomXName ); | |||||
| pBdr.Add( new XElement( borderPositionXName ) ); | |||||
| var border = pBdr.Element( borderPositionXName ); | |||||
| //Set bottom's attribute | |||||
| bottom.SetAttributeValue( XName.Get( "val", DocX.w.NamespaceName ), lineType ); | |||||
| bottom.SetAttributeValue( XName.Get( "sz", DocX.w.NamespaceName ), size.ToString() ); | |||||
| bottom.SetAttributeValue( XName.Get( "space", DocX.w.NamespaceName ), space.ToString() ); | |||||
| bottom.SetAttributeValue( XName.Get( "color", DocX.w.NamespaceName ), color ); | |||||
| //Set border's attribute | |||||
| border.SetAttributeValue( XName.Get( "val", DocX.w.NamespaceName ), lineType ); | |||||
| border.SetAttributeValue( XName.Get( "sz", DocX.w.NamespaceName ), size.ToString() ); | |||||
| border.SetAttributeValue( XName.Get( "space", DocX.w.NamespaceName ), space.ToString() ); | |||||
| border.SetAttributeValue( XName.Get( "color", DocX.w.NamespaceName ), color ); | |||||
| } | } | ||||
| } | } | ||||
| RemoveHyperlinkRecursive( e, index, ref count, ref found ); | RemoveHyperlinkRecursive( e, index, ref count, ref found ); | ||||
| } | } | ||||
| internal void ResetBackers() | |||||
| { | |||||
| ParagraphNumberPropertiesBacker = null; | |||||
| IsListItemBacker = null; | |||||
| IndentLevelBacker = null; | |||||
| } | |||||
| /// <summary> | /// <summary> | ||||
| /// Create a new Picture. | /// Create a new Picture. | ||||
| /// </summary> | /// </summary> | ||||
| { | { | ||||
| var part = document._package.GetPart( document.PackagePart.GetRelationship( id ).TargetUri ); | var part = document._package.GetPart( document.PackagePart.GetRelationship( id ).TargetUri ); | ||||
| var newDocPrIdValue = 1; | |||||
| var bookmarkIds = new List<string>(); | |||||
| var bookmarks = document.Xml.Descendants( XName.Get( "bookmarkStart", DocX.wp.NamespaceName ) ); | |||||
| foreach( var bookmark in bookmarks ) | |||||
| { | |||||
| var idAttr = bookmark.Attributes().FirstOrDefault( a => a.Name.LocalName == "id" ); | |||||
| if( idAttr != null ) | |||||
| { | |||||
| bookmarkIds.Add( idAttr.Value ); | |||||
| } | |||||
| } | |||||
| while( bookmarkIds.Contains( newDocPrIdValue.ToString() ) ) | |||||
| { | |||||
| ++newDocPrIdValue; | |||||
| } | |||||
| long newDocPrId = document.GetNextFreeDocPrId(); | |||||
| int cx, cy; | |||||
| var docPrs = document.Xml.Descendants( XName.Get( "docPr", DocX.wp.NamespaceName ) ); | |||||
| foreach( var bookmark in docPrs ) | |||||
| using( PackagePartStream packagePartStream = new PackagePartStream( part.GetStream() ) ) | |||||
| { | { | ||||
| var idAttr = bookmark.Attributes().FirstOrDefault( a => a.Name.LocalName == "id" ); | |||||
| if( idAttr != null ) | |||||
| using( System.Drawing.Image img = System.Drawing.Image.FromStream( packagePartStream, useEmbeddedColorManagement: false, validateImageData: false ) ) | |||||
| { | { | ||||
| bookmarkIds.Add( idAttr.Value ); | |||||
| cx = img.Width * 9526; | |||||
| cy = img.Height * 9526; | |||||
| } | } | ||||
| } | } | ||||
| while( bookmarkIds.Contains( newDocPrIdValue.ToString() ) ) | |||||
| { | |||||
| ++newDocPrIdValue; | |||||
| } | |||||
| int cx, cy; | |||||
| using( System.Drawing.Image img = System.Drawing.Image.FromStream( new PackagePartStream( part.GetStream() ) ) ) | |||||
| { | |||||
| cx = img.Width * 9526; | |||||
| cy = img.Height * 9526; | |||||
| } | |||||
| var e = new XElement( DocX.w + "drawing" ); | |||||
| var xml = XElement.Parse | var xml = XElement.Parse | ||||
| ( string.Format( @" | ( string.Format( @" | ||||
| </wp:inline> | </wp:inline> | ||||
| </w:drawing> | </w:drawing> | ||||
| </w:r> | </w:r> | ||||
| ", cx, cy, id, name, descr, newDocPrIdValue.ToString() ) ); | |||||
| ", cx, cy, id, name, descr, newDocPrId.ToString() ) ); | |||||
| var picture = new Picture( document, xml, new Image( document, document.PackagePart.GetRelationship( id ) ) ); | var picture = new Picture( document, xml, new Image( document, document.PackagePart.GetRelationship( id ) ) ); | ||||
| if( width > -1 ) | if( width > -1 ) | ||||
| } | } | ||||
| count -= HelperFunctions.GetSize( Xml ); | count -= HelperFunctions.GetSize( Xml ); | ||||
| count = Math.Max( 0, count ); | |||||
| // We have found the element, now find the run it belongs to. | // We have found the element, now find the run it belongs to. | ||||
| while( ( Xml.Name.LocalName != "r" ) && ( Xml.Name.LocalName != "pPr" ) ) | |||||
| while( ( Xml.Name.LocalName != "r" ) ) | |||||
| { | { | ||||
| Xml = Xml.Parent; | Xml = Xml.Parent; | ||||
| if( Xml == null ) | |||||
| return; | |||||
| } | } | ||||
| theOne = new Run( Document, Xml, count ); | theOne = new Run( Document, Xml, count ); | ||||
| string image_uri_string = p._img._pr.TargetUri.OriginalString; | string image_uri_string = p._img._pr.TargetUri.OriginalString; | ||||
| // Search for a relationship with a TargetUri that points at this Image. | // Search for a relationship with a TargetUri that points at this Image. | ||||
| var Id = | |||||
| ( | |||||
| from r in this.PackagePart.GetRelationshipsByType( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" ) | |||||
| where r.TargetUri.OriginalString == image_uri_string | |||||
| select r.Id | |||||
| ).SingleOrDefault(); | |||||
| string id = null; | |||||
| foreach( var r in this.PackagePart.GetRelationshipsByType( DocX.RelationshipImage ) ) | |||||
| { | |||||
| if( string.Equals( r.TargetUri.OriginalString, image_uri_string, StringComparison.Ordinal ) ) | |||||
| { | |||||
| id = r.Id; | |||||
| break; | |||||
| } | |||||
| } | |||||
| // If such a relation dosen't exist, create one. | |||||
| if( Id == null ) | |||||
| // If such a relation doesn't exist, create one. | |||||
| if( id == null ) | |||||
| { | { | ||||
| // Check to see if a relationship for this Picture exists and create it if not. | // Check to see if a relationship for this Picture exists and create it if not. | ||||
| var pr = this.PackagePart.CreateRelationship( p._img._pr.TargetUri, TargetMode.Internal, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" ); | |||||
| Id = pr.Id; | |||||
| var pr = this.PackagePart.CreateRelationship( p._img._pr.TargetUri, TargetMode.Internal, DocX.RelationshipImage ); | |||||
| id = pr.Id; | |||||
| } | } | ||||
| return Id; | |||||
| return id; | |||||
| } | } | ||||
| internal string GetOrGenerateRel( Hyperlink h ) | internal string GetOrGenerateRel( Hyperlink h ) | ||||
| { | { | ||||
| string image_uri_string = h.Uri.OriginalString; | |||||
| string image_uri_string = (h.Uri != null) ? h.Uri.OriginalString : null; | |||||
| // Search for a relationship with a TargetUri that points at this Image. | // Search for a relationship with a TargetUri that points at this Image. | ||||
| var Id = | var Id = | ||||
| ).SingleOrDefault(); | ).SingleOrDefault(); | ||||
| // If such a relation dosen't exist, create one. | // If such a relation dosen't exist, create one. | ||||
| if( Id == null ) | |||||
| if( (Id == null) && ( h.Uri != null) ) | |||||
| { | { | ||||
| // Check to see if a relationship for this Picture exists and create it if not. | // Check to see if a relationship for this Picture exists and create it if not. | ||||
| var pr = this.PackagePart.CreateRelationship( h.Uri, TargetMode.External, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" ); | var pr = this.PackagePart.CreateRelationship( h.Uri, TargetMode.External, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" ); | ||||
| private XElement GetParagraphNumberProperties() | private XElement GetParagraphNumberProperties() | ||||
| { | { | ||||
| var numPrNode = Xml.Descendants().FirstOrDefault( el => el.Name.LocalName == "numPr" ); | var numPrNode = Xml.Descendants().FirstOrDefault( el => el.Name.LocalName == "numPr" ); | ||||
| if( numPrNode != null ) | |||||
| { | |||||
| var numIdNode = numPrNode.Descendants().First( numId => numId.Name.LocalName == "numId" ); | |||||
| var numIdAttribute = numIdNode.Attribute( DocX.w + "val" ); | |||||
| if( numIdAttribute != null && numIdAttribute.Value.Equals( "0" ) ) | |||||
| return null; | |||||
| } | |||||
| return numPrNode; | return numPrNode; | ||||
| } | } | ||||
| style.Remove(); | style.Remove(); | ||||
| } | } | ||||
| if( _design == TableDesign.Custom ) | |||||
| { | |||||
| if( string.IsNullOrEmpty( _customTableDesignName ) ) | |||||
| { | |||||
| _design = TableDesign.None; | |||||
| if( style != null ) | |||||
| style.Remove(); | |||||
| } | |||||
| else | |||||
| { | |||||
| val.Value = _customTableDesignName; | |||||
| } | |||||
| } | |||||
| else | |||||
| if( _design != TableDesign.Custom ) | |||||
| { | { | ||||
| switch( _design ) | switch( _design ) | ||||
| { | { | ||||
| let styleId = e.Attribute( XName.Get( "styleId", DocX.w.NamespaceName ) ) | let styleId = e.Attribute( XName.Get( "styleId", DocX.w.NamespaceName ) ) | ||||
| where ( styleId != null && styleId.Value == val.Value ) | where ( styleId != null && styleId.Value == val.Value ) | ||||
| select e | select e | ||||
| ).First(); | |||||
| ).FirstOrDefault(); | |||||
| Document._styles.Element( XName.Get( "styles", DocX.w.NamespaceName ) ).Add( styleElement ); | |||||
| if( styleElement != null ) | |||||
| Document._styles.Element( XName.Get( "styles", DocX.w.NamespaceName ) ).Add( styleElement ); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| set; | set; | ||||
| } | } | ||||
| public List<Double> ColumnWidths | |||||
| { | |||||
| get | |||||
| { | |||||
| var columnWidths = new List<Double>(); | |||||
| // get the table grid property | |||||
| XElement grid = Xml.Element( XName.Get( "tblGrid", DocX.w.NamespaceName ) ); | |||||
| // get the columns properties | |||||
| var columns = grid?.Elements( XName.Get( "gridCol", DocX.w.NamespaceName ) ); | |||||
| if( columns == null ) | |||||
| return null; | |||||
| foreach( var column in columns ) | |||||
| { | |||||
| string value = column.GetAttribute( XName.Get( "w", DocX.w.NamespaceName ) ); | |||||
| columnWidths.Add( Convert.ToDouble( value, new CultureInfo( "en-US" ) ) ); | |||||
| } | |||||
| return columnWidths; | |||||
| } | |||||
| } | |||||
| #endregion | #endregion | ||||
| #region Constructors | #region Constructors | ||||
| /// Insert a copy of a row at the end of this table. | /// Insert a copy of a row at the end of this table. | ||||
| /// </summary> | /// </summary> | ||||
| /// <returns>A new row.</returns> | /// <returns>A new row.</returns> | ||||
| public Row InsertRow( Row row ) | |||||
| public Row InsertRow( Row row, bool keepFormatting = false ) | |||||
| { | { | ||||
| return this.InsertRow( row, this.RowCount ); | |||||
| return this.InsertRow( row, this.RowCount, keepFormatting ); | |||||
| } | } | ||||
| /// <summary> | /// <summary> | ||||
| /// </summary> | /// </summary> | ||||
| /// <param name="row">Row to copy and insert.</param> | /// <param name="row">Row to copy and insert.</param> | ||||
| /// <param name="index">Index to insert row at.</param> | /// <param name="index">Index to insert row at.</param> | ||||
| /// <param name="keepFormatting">True to clone everithing, False to clone cell structure only.</param> | |||||
| /// <returns>A new Row</returns> | /// <returns>A new Row</returns> | ||||
| public Row InsertRow( Row row, int index ) | |||||
| public Row InsertRow( Row row, int index, bool keepFormatting = false ) | |||||
| { | { | ||||
| if( row == null ) | if( row == null ) | ||||
| throw new ArgumentNullException( "row" ); | throw new ArgumentNullException( "row" ); | ||||
| if( index < 0 || index > RowCount ) | if( index < 0 || index > RowCount ) | ||||
| throw new IndexOutOfRangeException(); | throw new IndexOutOfRangeException(); | ||||
| var content = row.Xml.Elements( XName.Get( "tc", DocX.w.NamespaceName ) ).Select( element => HelperFunctions.CloneElement( element ) ).ToList(); | |||||
| return this.InsertRow( content, index ); | |||||
| List<XElement> content; | |||||
| if( keepFormatting ) | |||||
| content = row.Xml.Elements().Select( element => HelperFunctions.CloneElement( element ) ).ToList(); | |||||
| else | |||||
| content = row.Xml.Elements( XName.Get( "tc", DocX.w.NamespaceName ) ).Select( element => HelperFunctions.CloneElement( element ) ).ToList(); | |||||
| return InsertRow( content, index ); | |||||
| } | } | ||||
| /// <summary> | /// <summary> | ||||
| this.AutoFit = AutoFit.Fixed; | this.AutoFit = AutoFit.Fixed; | ||||
| } | } | ||||
| public List<Double> ColumnWidths | |||||
| { | |||||
| get | |||||
| { | |||||
| var columnWidths = new List<Double>(); | |||||
| // get the table grid property | |||||
| XElement grid = Xml.Element( XName.Get( "tblGrid", DocX.w.NamespaceName ) ); | |||||
| // get the columns properties | |||||
| var columns = grid?.Elements( XName.Get( "gridCol", DocX.w.NamespaceName ) ); | |||||
| if( columns == null ) | |||||
| return null; | |||||
| foreach( var column in columns ) | |||||
| { | |||||
| string value = column.GetAttribute( XName.Get( "w", DocX.w.NamespaceName ) ); | |||||
| columnWidths.Add( Convert.ToDouble( value, new CultureInfo("en-US" ) ) ); | |||||
| } | |||||
| return columnWidths; | |||||
| } | |||||
| } | |||||
| public void SetTableCellMargin( TableCellMarginType type, double margin ) | public void SetTableCellMargin( TableCellMarginType type, double margin ) | ||||
| { | { | ||||
| var tblPr = this.GetOrCreate_tblPr(); | var tblPr = this.GetOrCreate_tblPr(); | ||||
| trPr = Xml.Element( XName.Get( "trPr", DocX.w.NamespaceName ) ); | trPr = Xml.Element( XName.Get( "trPr", DocX.w.NamespaceName ) ); | ||||
| } | } | ||||
| XElement tc = Xml.Element( XName.Get( "tc", DocX.w.NamespaceName ) ); | |||||
| if( tc != null ) | |||||
| { | |||||
| trPr.Remove(); | |||||
| tc.AddBeforeSelf( trPr ); | |||||
| } | |||||
| XElement trHeight = trPr.Element( XName.Get( "trHeight", DocX.w.NamespaceName ) ); | XElement trHeight = trPr.Element( XName.Get( "trHeight", DocX.w.NamespaceName ) ); | ||||
| if( trHeight == null ) | if( trHeight == null ) | ||||
| { | { | ||||
| trHeight.SetAttributeValue( XName.Get( "hRule", DocX.w.NamespaceName ), isHeightExact ? "exact" : "atLeast" ); | trHeight.SetAttributeValue( XName.Get( "hRule", DocX.w.NamespaceName ), isHeightExact ? "exact" : "atLeast" ); | ||||
| // Using 20 to match DocX._pageSizeMultiplier. | // Using 20 to match DocX._pageSizeMultiplier. | ||||
| trHeight.SetAttributeValue( XName.Get( "val", DocX.w.NamespaceName ), ( height * 20 ).ToString() ); | |||||
| trHeight.SetAttributeValue( XName.Get( "val", DocX.w.NamespaceName ), ( ( int )( Math.Round( height * 20, 0 ) ) ).ToString( CultureInfo.InvariantCulture ) ); | |||||
| } | } | ||||
| #endregion | #endregion | ||||
| } | } | ||||
| } | } | ||||
| /// <summary> | |||||
| /// Gets or Sets this Cells vertical alignment. | |||||
| /// </summary> | |||||
| /// <example> | |||||
| /// Creates a table with 3 cells and sets the vertical alignment of each to 1 of the 3 available options. | |||||
| /// <code> | |||||
| ///// Create a new document. | |||||
| ///using(DocX document = DocX.Create("Test.docx")) | |||||
| ///{ | |||||
| /// // Insert a Table into this document. | |||||
| /// Table t = document.InsertTable(3, 1); | |||||
| /// | |||||
| /// // Set the design of the Table such that we can easily identify cell boundaries. | |||||
| /// t.Design = TableDesign.TableGrid; | |||||
| /// | |||||
| /// // Set the height of the row bigger than default. | |||||
| /// // We need to be able to see the difference in vertical cell alignment options. | |||||
| /// t.Rows[0].Height = 100; | |||||
| /// | |||||
| /// // Set the vertical alignment of cell0 to top. | |||||
| /// Cell c0 = t.Rows[0].Cells[0]; | |||||
| /// c0.InsertParagraph("VerticalAlignment.Top"); | |||||
| /// c0.VerticalAlignment = VerticalAlignment.Top; | |||||
| /// | |||||
| /// // Set the vertical alignment of cell1 to center. | |||||
| /// Cell c1 = t.Rows[0].Cells[1]; | |||||
| /// c1.InsertParagraph("VerticalAlignment.Center"); | |||||
| /// c1.VerticalAlignment = VerticalAlignment.Center; | |||||
| /// | |||||
| /// // Set the vertical alignment of cell2 to bottom. | |||||
| /// Cell c2 = t.Rows[0].Cells[2]; | |||||
| /// c2.InsertParagraph("VerticalAlignment.Bottom"); | |||||
| /// c2.VerticalAlignment = VerticalAlignment.Bottom; | |||||
| /// | |||||
| /// // Save the document. | |||||
| /// document.Save(); | |||||
| ///} | |||||
| /// </code> | |||||
| /// </example> | |||||
| // <summary> | |||||
| // Gets or Sets this Cells vertical alignment. | |||||
| // </summary> | |||||
| // <example> | |||||
| // Creates a table with 3 cells and sets the vertical alignment of each to 1 of the 3 available options. | |||||
| // <code> | |||||
| // Create a new document. | |||||
| //using(DocX document = DocX.Create("Test.docx")) | |||||
| //{ | |||||
| // // Insert a Table into this document. | |||||
| // Table t = document.InsertTable(3, 1); | |||||
| // | |||||
| // // Set the design of the Table such that we can easily identify cell boundaries. | |||||
| // t.Design = TableDesign.TableGrid; | |||||
| // | |||||
| // // Set the height of the row bigger than default. | |||||
| // // We need to be able to see the difference in vertical cell alignment options. | |||||
| // t.Rows[0].Height = 100; | |||||
| // | |||||
| // // Set the vertical alignment of cell0 to top. | |||||
| // Cell c0 = t.Rows[0].Cells[0]; | |||||
| // c0.InsertParagraph("VerticalAlignment.Top"); | |||||
| // c0.VerticalAlignment = VerticalAlignment.Top; | |||||
| // | |||||
| // // Set the vertical alignment of cell1 to center. | |||||
| // Cell c1 = t.Rows[0].Cells[1]; | |||||
| // c1.InsertParagraph("VerticalAlignment.Center"); | |||||
| // c1.VerticalAlignment = VerticalAlignment.Center; | |||||
| // | |||||
| // // Set the vertical alignment of cell2 to bottom. | |||||
| // Cell c2 = t.Rows[0].Cells[2]; | |||||
| // c2.InsertParagraph("VerticalAlignment.Bottom"); | |||||
| // c2.VerticalAlignment = VerticalAlignment.Bottom; | |||||
| // | |||||
| // // Save the document. | |||||
| // document.Save(); | |||||
| //} | |||||
| // </code> | |||||
| // </example> | |||||
| public VerticalAlignment VerticalAlignment | public VerticalAlignment VerticalAlignment | ||||
| { | { | ||||
| get | get | ||||
| #region Public Methods | #region Public Methods | ||||
| /// <summary> | |||||
| /// Set the table cell border | |||||
| /// </summary> | |||||
| /// <example> | |||||
| /// <code> | |||||
| ///// Create a new document. | |||||
| ///using (DocX document = DocX.Create("Test.docx")) | |||||
| ///{ | |||||
| /// // Insert a table into this document. | |||||
| /// Table t = document.InsertTable(3, 3); | |||||
| /// | |||||
| /// // Get the center cell. | |||||
| /// Cell center = t.Rows[1].Cells[1]; | |||||
| /// | |||||
| /// // Create a large blue border. | |||||
| /// Border b = new Border(BorderStyle.Tcbs_single, BorderSize.seven, 0, Color.Blue); | |||||
| /// | |||||
| /// // Set the center cells Top, Bottom, Left and Right Borders to b. | |||||
| /// center.SetBorder(TableCellBorderType.Top, b); | |||||
| /// center.SetBorder(TableCellBorderType.Bottom, b); | |||||
| /// center.SetBorder(TableCellBorderType.Left, b); | |||||
| /// center.SetBorder(TableCellBorderType.Right, b); | |||||
| /// | |||||
| /// // Save the document. | |||||
| /// document.Save(); | |||||
| ///} | |||||
| /// </code> | |||||
| /// </example> | |||||
| /// <param name="borderType">Table Cell border to set</param> | |||||
| /// <param name="border">Border object to set the table cell border</param> | |||||
| // <summary> | |||||
| // Set the table cell border | |||||
| // </summary> | |||||
| // <example> | |||||
| // <code> | |||||
| // Create a new document. | |||||
| //using (DocX document = DocX.Create("Test.docx")) | |||||
| //{ | |||||
| // // Insert a table into this document. | |||||
| // Table t = document.InsertTable(3, 3); | |||||
| // | |||||
| // // Get the center cell. | |||||
| // Cell center = t.Rows[1].Cells[1]; | |||||
| // | |||||
| // // Create a large blue border. | |||||
| // Border b = new Border(BorderStyle.Tcbs_single, BorderSize.seven, 0, Color.Blue); | |||||
| // | |||||
| // // Set the center cells Top, Bottom, Left and Right Borders to b. | |||||
| // center.SetBorder(TableCellBorderType.Top, b); | |||||
| // center.SetBorder(TableCellBorderType.Bottom, b); | |||||
| // center.SetBorder(TableCellBorderType.Left, b); | |||||
| // center.SetBorder(TableCellBorderType.Right, b); | |||||
| // | |||||
| // // Save the document. | |||||
| // document.Save(); | |||||
| //} | |||||
| // </code> | |||||
| // </example> | |||||
| // <param name="borderType">Table Cell border to set</param> | |||||
| // <param name="border">Border object to set the table cell border</param> | |||||
| public void SetBorder( TableCellBorderType borderType, Border border ) | public void SetBorder( TableCellBorderType borderType, Border border ) | ||||
| { | { | ||||
| /* | /* | ||||
| #endregion | #endregion | ||||
| /// <summary> | |||||
| /// Gets or Sets the fill color of this Cell. | |||||
| /// </summary> | |||||
| /// <example> | |||||
| /// <code> | |||||
| /// // Create a new document. | |||||
| /// using (DocX document = DocX.Create("Test.docx")) | |||||
| /// { | |||||
| /// // Insert a table into this document. | |||||
| /// Table t = document.InsertTable(3, 3); | |||||
| /// | |||||
| /// // Fill the first cell as Blue. | |||||
| /// t.Rows[0].Cells[0].FillColor = Color.Blue; | |||||
| /// // Fill the middle cell as Red. | |||||
| /// t.Rows[1].Cells[1].FillColor = Color.Red; | |||||
| /// // Fill the last cell as Green. | |||||
| /// t.Rows[2].Cells[2].FillColor = Color.Green; | |||||
| /// | |||||
| /// // Save the document. | |||||
| /// document.Save(); | |||||
| /// } | |||||
| /// </code> | |||||
| /// </example> | |||||
| // <summary> | |||||
| // Gets or Sets the fill color of this Cell. | |||||
| // </summary> | |||||
| // <example> | |||||
| // <code> | |||||
| // // Create a new document. | |||||
| // using (DocX document = DocX.Create("Test.docx")) | |||||
| // { | |||||
| // // Insert a table into this document. | |||||
| // Table t = document.InsertTable(3, 3); | |||||
| // | |||||
| // // Fill the first cell as Blue. | |||||
| // t.Rows[0].Cells[0].FillColor = Color.Blue; | |||||
| // // Fill the middle cell as Red. | |||||
| // t.Rows[1].Cells[1].FillColor = Color.Red; | |||||
| // // Fill the last cell as Green. | |||||
| // t.Rows[2].Cells[2].FillColor = Color.Green; | |||||
| // | |||||
| // // Save the document. | |||||
| // document.Save(); | |||||
| // } | |||||
| // </code> | |||||
| // </example> | |||||
| } | } | ||||
| public class TableLook | public class TableLook |
| return table; | return table; | ||||
| } | } | ||||
| public virtual List InsertListAfterSelf( List list ) | |||||
| { | |||||
| for( var i = list.Items.Count - 1; i >= 0; --i ) | |||||
| { | |||||
| this.Xml.AddAfterSelf( list.Items[ i ].Xml ); | |||||
| } | |||||
| return list; | |||||
| } | |||||
| public virtual List InsertListBeforeSelf( List list ) | |||||
| { | |||||
| foreach( var item in list.Items ) | |||||
| { | |||||
| this.Xml.AddBeforeSelf( item.Xml ); | |||||
| } | |||||
| return list; | |||||
| } | |||||
| #endregion | #endregion | ||||
| } | } | ||||
| Body | Body | ||||
| } | } | ||||
| public enum ShadingType | |||||
| { | |||||
| Text, | |||||
| Paragraph | |||||
| } | |||||
| public enum PageNumberFormat | public enum PageNumberFormat | ||||
| { | { | ||||
| normal, | normal, | ||||
| bottom, | bottom, | ||||
| top | top | ||||
| } | } | ||||
| public enum HorizontalBorderPosition | |||||
| { | |||||
| top, | |||||
| bottom | |||||
| } | |||||
| public enum TabStopPositionLeader | |||||
| { | |||||
| none, | |||||
| dot, | |||||
| underscore, | |||||
| hyphen | |||||
| } | |||||
| } | } |
| D:\Dev\DocumentLibraries\Release\1.2.0\OpenSource\Generated\Xceed.Words.NET\bin\Release\Xceed.Words.NET.dll | |||||
| D:\Dev\DocumentLibraries\Release\1.2.0\OpenSource\Generated\Xceed.Words.NET\obj\Release\Xceed.Words.NET.csprojResolveAssemblyReference.cache | |||||
| D:\Dev\DocumentLibraries\Release\1.2.0\OpenSource\Generated\Xceed.Words.NET\obj\Release\Xceed.Words.NET.dll |