11namespace MiniSoftware
22{
3- using DocumentFormat . OpenXml ;
4- using DocumentFormat . OpenXml . Packaging ;
5- using DocumentFormat . OpenXml . Wordprocessing ;
3+ using DocumentFormat . OpenXml ;
4+ using DocumentFormat . OpenXml . Packaging ;
5+ using DocumentFormat . OpenXml . Wordprocessing ;
6+ using System ;
67 using System . Collections . Generic ;
78 using System . IO ;
89 using System . Linq ;
910 using System . Text . RegularExpressions ;
11+ using A = DocumentFormat . OpenXml . Drawing ;
12+ using DW = DocumentFormat . OpenXml . Drawing . Wordprocessing ;
13+ using PIC = DocumentFormat . OpenXml . Drawing . Pictures ;
1014
1115 public static class MiniWord
1216 {
1317 static void ReplaceTag ( this OpenXmlElement xmlElement , WordprocessingDocument docx , Dictionary < string , object > tags )
1418 {
1519 var paragraphs = xmlElement . Descendants < Paragraph > ( ) ;
20+ // Avoid not standard string format e.g. {{<t>tag</t>}}
21+ foreach ( var tag in tags )
22+ {
23+ var regexStr = string . Concat ( @"((\{\{(?:(?!\{\{|}}).)*>)|\{\{)" , tag . Key , @"(}}|<.*?}})" ) ;
24+
25+ xmlElement . InnerXml = Regex . Replace ( xmlElement . InnerXml , regexStr , $ "{{{{{tag.Key?.ToString()}}}}}", RegexOptions . Singleline | RegexOptions . IgnorePatternWhitespace | RegexOptions . CultureInvariant ) ;
26+ }
27+ //return;
1628 foreach ( var p in paragraphs )
1729 {
18- var innerXmlSb = p . InnerXml ;
19- foreach ( var tag in tags )
30+ var runs = p . Descendants < Run > ( ) ;
31+ foreach ( var run in runs )
2032 {
21- innerXmlSb = Regex . Replace ( innerXmlSb , @"((\{\{(?:(?!\{\{|}}).)*>)|\{\{)" + tag . Key + @"(}}|<.*?}})" , tags [ tag . Key ] ? . ToString ( ) , RegexOptions . Singleline | RegexOptions . IgnorePatternWhitespace | RegexOptions . CultureInvariant ) ;
33+ foreach ( Text t in run . Descendants < Text > ( ) )
34+ {
35+ foreach ( var tag in tags )
36+ {
37+ var isMatch = t . Text . Contains ( $ "{{{{{tag.Key}}}}}") ;
38+ if ( isMatch )
39+ {
40+ if ( tag . Value is MiniWordPicture )
41+ {
42+ var pic = ( MiniWordPicture ) tag . Value ;
43+ byte [ ] l_Data = null ;
44+ if ( pic . Path != null )
45+ {
46+ l_Data = File . ReadAllBytes ( pic . Path ) ;
47+ }
48+ if ( pic . Bytes != null )
49+ {
50+ l_Data = pic . Bytes ;
51+ }
52+
53+ var mainPart = docx . MainDocumentPart ;
54+ var imagePart = mainPart . AddImagePart ( ImagePartType . Png ) ; //TODO: jpg..
55+ using ( var stream = new MemoryStream ( l_Data ) )
56+ {
57+ imagePart . FeedData ( stream ) ;
58+ AddPicture ( run , mainPart . GetIdOfPart ( imagePart ) , pic ) ;
59+ }
60+ t . Remove ( ) ;
61+ }
62+ else
63+ {
64+ t . Text = t . Text . Replace ( $ "{{{{{tag.Key}}}}}", tag . Value ? . ToString ( ) ) ;
65+ }
66+ }
67+ }
68+ }
2269 }
23- p . InnerXml = innerXmlSb ;
2470 }
2571 }
72+
73+ private static void AddPicture ( OpenXmlElement appendElement , string relationshipId , MiniWordPicture pic )
74+ {
75+ // Define the reference of the image.
76+ var element =
77+ new Drawing (
78+ new DW . Inline (
79+ new DW . Extent ( ) { Cx = pic . Width , Cy = pic . Height } ,
80+ new DW . EffectExtent ( )
81+ {
82+ LeftEdge = 0L ,
83+ TopEdge = 0L ,
84+ RightEdge = 0L ,
85+ BottomEdge = 0L
86+ } ,
87+ new DW . DocProperties ( )
88+ {
89+ Id = ( UInt32Value ) 1U ,
90+ Name = $ "Picture { Guid . NewGuid ( ) . ToString ( ) } "
91+ } ,
92+ new DW . NonVisualGraphicFrameDrawingProperties (
93+ new A . GraphicFrameLocks ( ) { NoChangeAspect = true } ) ,
94+ new A . Graphic (
95+ new A . GraphicData (
96+ new PIC . Picture (
97+ new PIC . NonVisualPictureProperties (
98+ new PIC . NonVisualDrawingProperties ( )
99+ {
100+ Id = ( UInt32Value ) 0U ,
101+ Name = $ "New Bitmap Image{ Guid . NewGuid ( ) . ToString ( ) } .png"
102+ } ,
103+ new PIC . NonVisualPictureDrawingProperties ( ) ) ,
104+ new PIC . BlipFill (
105+ new A . Blip (
106+ new A . BlipExtensionList (
107+ new A . BlipExtension ( )
108+ {
109+ Uri =
110+ $ "{{{ Guid.NewGuid().ToString(" n")}}}"
111+ } )
112+ )
113+ {
114+ Embed = relationshipId ,
115+ CompressionState =
116+ A . BlipCompressionValues . Print
117+ } ,
118+ new A . Stretch (
119+ new A . FillRectangle ( ) ) ) ,
120+ new PIC . ShapeProperties (
121+ new A . Transform2D (
122+ new A . Offset ( ) { X = 0L , Y = 0L } ,
123+ new A . Extents ( ) { Cx = pic . Width , Cy = pic . Height } ) ,
124+ new A . PresetGeometry (
125+ new A . AdjustValueList ( )
126+ )
127+ { Preset = A . ShapeTypeValues . Rectangle } ) )
128+ )
129+ { Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" } )
130+ )
131+ {
132+ DistanceFromTop = ( UInt32Value ) 0U ,
133+ DistanceFromBottom = ( UInt32Value ) 0U ,
134+ DistanceFromLeft = ( UInt32Value ) 0U ,
135+ DistanceFromRight = ( UInt32Value ) 0U ,
136+ EditId = "50D07946"
137+ } ) ;
138+ appendElement . Append ( ( element ) ) ;
139+ }
26140 public static void SaveAsByTemplate ( string path , string templatePath , object value )
27141 {
28142 using ( var stream = File . Create ( path ) )
@@ -46,7 +160,7 @@ public static void SaveAsByTemplate(this Stream stream, byte[] templateBytes, ob
46160 }
47161 private static byte [ ] GetBytes ( string path )
48162 {
49- using ( var st = FileHelper . OpenSharedRead ( path ) )
163+ using ( var st = Helpers . OpenSharedRead ( path ) )
50164 using ( var ms = new MemoryStream ( ) )
51165 {
52166 st . CopyTo ( ms ) ;
@@ -75,9 +189,4 @@ private static void SaveAsByTemplateImpl(Stream stream, byte[] template, object
75189 stream . Write ( bytes , 0 , bytes . Length ) ;
76190 }
77191 }
78-
79- internal static partial class FileHelper
80- {
81- public static FileStream OpenSharedRead ( string path ) => File . Open ( path , FileMode . Open , FileAccess . Read , FileShare . ReadWrite ) ;
82- }
83192}
0 commit comments