You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Table.cs 162KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Xml.Linq;
  5. using System.IO.Packaging;
  6. using System.IO;
  7. using System.Drawing;
  8. using System.Globalization;
  9. using System.Collections.ObjectModel;
  10. namespace Novacode
  11. {
  12. /// <summary>
  13. /// Represents a Table in a document.
  14. /// </summary>
  15. public class Table : InsertBeforeOrAfter
  16. {
  17. private Alignment alignment;
  18. private AutoFit autofit;
  19. private float[] ColumnWidthsValue;
  20. /// <summary>
  21. /// Merge cells in given column starting with startRow and ending with endRow.
  22. /// </summary>
  23. /// <remarks>
  24. /// Added by arudoy patch: 11608
  25. /// </remarks>
  26. public void MergeCellsInColumn(int columnIndex, int startRow, int endRow)
  27. {
  28. // Check for valid start and end indexes.
  29. if (columnIndex < 0 || columnIndex >= ColumnCount)
  30. throw new IndexOutOfRangeException();
  31. if (startRow < 0 || endRow <= startRow || endRow >= Rows.Count)
  32. throw new IndexOutOfRangeException();
  33. // Foreach each Cell between startIndex and endIndex inclusive.
  34. foreach (Row row in Rows.Where((z, i) => i > startRow && i <= endRow))
  35. {
  36. Cell c = row.Cells[columnIndex];
  37. XElement tcPr = c.Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  38. if (tcPr == null)
  39. {
  40. c.Xml.SetElementValue(XName.Get("tcPr", DocX.w.NamespaceName), string.Empty);
  41. tcPr = c.Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  42. }
  43. XElement vMerge = tcPr.Element(XName.Get("vMerge", DocX.w.NamespaceName));
  44. if (vMerge == null)
  45. {
  46. tcPr.SetElementValue(XName.Get("vMerge", DocX.w.NamespaceName), string.Empty);
  47. vMerge = tcPr.Element(XName.Get("vMerge", DocX.w.NamespaceName));
  48. }
  49. }
  50. /*
  51. * Get the tcPr (table cell properties) element for the first cell in this merge,
  52. * null will be returned if no such element exists.
  53. */
  54. XElement start_tcPr = null;
  55. if (columnIndex > Rows[startRow].Cells.Count)
  56. start_tcPr = Rows[startRow].Cells[Rows[startRow].Cells.Count - 1].Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  57. else
  58. start_tcPr = Rows[startRow].Cells[columnIndex].Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  59. if (start_tcPr == null)
  60. {
  61. Rows[startRow].Cells[columnIndex].Xml.SetElementValue(XName.Get("tcPr", DocX.w.NamespaceName), string.Empty);
  62. start_tcPr = Rows[startRow].Cells[columnIndex].Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  63. }
  64. /*
  65. * Get the gridSpan element of this row,
  66. * null will be returned if no such element exists.
  67. */
  68. XElement start_vMerge = start_tcPr.Element(XName.Get("vMerge", DocX.w.NamespaceName));
  69. if (start_vMerge == null)
  70. {
  71. start_tcPr.SetElementValue(XName.Get("vMerge", DocX.w.NamespaceName), string.Empty);
  72. start_vMerge = start_tcPr.Element(XName.Get("vMerge", DocX.w.NamespaceName));
  73. }
  74. start_vMerge.SetAttributeValue(XName.Get("val", DocX.w.NamespaceName), "restart");
  75. }
  76. /// <summary>
  77. /// Returns a list of all Paragraphs inside this container.
  78. /// </summary>
  79. ///
  80. public virtual List<Paragraph> Paragraphs
  81. {
  82. get
  83. {
  84. List<Paragraph> paragraphs = new List<Paragraph>();
  85. foreach (Row r in Rows)
  86. paragraphs.AddRange(r.Paragraphs);
  87. return paragraphs;
  88. }
  89. }
  90. /// <summary>
  91. /// Returns a list of all Pictures in a Table.
  92. /// </summary>
  93. /// <example>
  94. /// Returns a list of all Pictures in a Table.
  95. /// <code>
  96. /// <![CDATA[
  97. /// // Create a document.
  98. /// using (DocX document = DocX.Load(@"Test.docx"))
  99. /// {
  100. /// // Get the first Table in a document.
  101. /// Table t = document.Tables[0];
  102. ///
  103. /// // Get all of the Pictures in this Table.
  104. /// List<Picture> pictures = t.Pictures;
  105. ///
  106. /// // Save this document.
  107. /// document.Save();
  108. /// }
  109. /// ]]>
  110. /// </code>
  111. /// </example>
  112. public List<Picture> Pictures
  113. {
  114. get
  115. {
  116. List<Picture> pictures = new List<Picture>();
  117. foreach (Row r in Rows)
  118. pictures.AddRange(r.Pictures);
  119. return pictures;
  120. }
  121. }
  122. /// <summary>
  123. /// Set the direction of all content in this Table.
  124. /// </summary>
  125. /// <param name="direction">(Left to Right) or (Right to Left)</param>
  126. /// <example>
  127. /// Set the content direction for all content in a table to RightToLeft.
  128. /// <code>
  129. /// // Load a document.
  130. /// using (DocX document = DocX.Load(@"Test.docx"))
  131. /// {
  132. /// // Get the first table in a document.
  133. /// Table table = document.Tables[0];
  134. ///
  135. /// // Set the content direction for all content in this table to RightToLeft.
  136. /// table.SetDirection(Direction.RightToLeft);
  137. ///
  138. /// // Save all changes made to this document.
  139. /// document.Save();
  140. /// }
  141. /// </code>
  142. /// </example>
  143. public void SetDirection(Direction direction)
  144. {
  145. XElement tblPr = GetOrCreate_tblPr();
  146. tblPr.Add(new XElement(DocX.w + "bidiVisual"));
  147. foreach (Row r in Rows)
  148. r.SetDirection(direction);
  149. }
  150. /// <summary>
  151. /// Get all of the Hyperlinks in this Table.
  152. /// </summary>
  153. /// <example>
  154. /// Get all of the Hyperlinks in this Table.
  155. /// <code>
  156. /// // Create a document.
  157. /// using (DocX document = DocX.Load(@"Test.docx"))
  158. /// {
  159. /// // Get the first Table in this document.
  160. /// Table t = document.Tables[0];
  161. ///
  162. /// // Get a list of all Hyperlinks in this Table.
  163. /// List&lt;Hyperlink&gt; hyperlinks = t.Hyperlinks;
  164. ///
  165. /// // Save this document.
  166. /// document.Save();
  167. /// }
  168. /// </code>
  169. /// </example>
  170. public List<Hyperlink> Hyperlinks
  171. {
  172. get
  173. {
  174. List<Hyperlink> hyperlinks = new List<Hyperlink>();
  175. foreach (Row r in Rows)
  176. hyperlinks.AddRange(r.Hyperlinks);
  177. return hyperlinks;
  178. }
  179. }
  180. public void SetWidths(float[] widths)
  181. {
  182. this.ColumnWidthsValue = widths;
  183. //set widths for existing rows
  184. foreach (var r in Rows)
  185. {
  186. for (var c = 0; c < widths.Length; c++)
  187. {
  188. if (r.Cells.Count > c)
  189. r.Cells[c].Width = widths[c];
  190. }
  191. }
  192. }
  193. /// <summary>
  194. /// Set Table column width by prescribing percent
  195. /// </summary>
  196. /// <param name="widthsPercentage">column width % list</param>
  197. /// <param name="totalWidth">Total table width. Will be calculated if null sent.</param>
  198. public void SetWidthsPercentage(float[] widthsPercentage, float? totalWidth)
  199. {
  200. if (totalWidth == null) totalWidth = this.Document.PageWidth - this.Document.MarginLeft - this.Document.MarginRight; // calculate total table width
  201. List<float> widths = new List<float>(widthsPercentage.Length); // empty list, will hold actual width
  202. widthsPercentage.ToList().ForEach(pWidth => { widths.Add(pWidth * totalWidth.Value / 100); }); // convert percentage to actual width for all values in array
  203. SetWidths(widths.ToArray()); // set actual column width
  204. }
  205. /// <summary>
  206. /// If the tblPr element doesent exist it is created, either way it is returned by this function.
  207. /// </summary>
  208. /// <returns>The tblPr element for this Table.</returns>
  209. internal XElement GetOrCreate_tblPr()
  210. {
  211. // Get the element.
  212. XElement tblPr = Xml.Element(XName.Get("tblPr", DocX.w.NamespaceName));
  213. // If it dosen't exist, create it.
  214. if (tblPr == null)
  215. {
  216. Xml.AddFirst(new XElement(XName.Get("tblPr", DocX.w.NamespaceName)));
  217. tblPr = Xml.Element(XName.Get("tblPr", DocX.w.NamespaceName));
  218. }
  219. // Return the pPr element for this Paragraph.
  220. return tblPr;
  221. }
  222. /// <summary>
  223. /// Set the specified cell margin for the table-level.
  224. /// </summary>
  225. /// <param name="type">The side of the cell margin.</param>
  226. /// <param name="margin">The value for the specified cell margin.</param>
  227. /// <remarks>More information can be found <see cref="http://msdn.microsoft.com/en-us/library/documentformat.openxml.wordprocessing.tablecellmargindefault.aspx">here</see></remarks>
  228. public void SetTableCellMargin(TableCellMarginType type, double margin)
  229. {
  230. XElement tblPr = GetOrCreate_tblPr();
  231. // find (or create) the element with the cell margins
  232. XElement tblCellMar = tblPr.Element(XName.Get("tblCellMar", DocX.w.NamespaceName));
  233. if (tblCellMar == null)
  234. {
  235. tblPr.AddFirst(new XElement(XName.Get("tblCellMar", DocX.w.NamespaceName)));
  236. tblCellMar = tblPr.Element(XName.Get("tblCellMar", DocX.w.NamespaceName));
  237. }
  238. // find (or create) the element with cell margin for the specified side
  239. XElement tblMargin = tblCellMar.Element(XName.Get(type.ToString(), DocX.w.NamespaceName));
  240. if (tblMargin == null)
  241. {
  242. tblCellMar.AddFirst(new XElement(XName.Get(type.ToString(), DocX.w.NamespaceName)));
  243. tblMargin = tblCellMar.Element(XName.Get(type.ToString(), DocX.w.NamespaceName));
  244. }
  245. tblMargin.RemoveAttributes();
  246. // set the value for the cell margin
  247. tblMargin.Add(new XAttribute(XName.Get("w", DocX.w.NamespaceName), margin));
  248. // set the side of cell margin
  249. tblMargin.Add(new XAttribute(XName.Get("type", DocX.w.NamespaceName), "dxa"));
  250. }
  251. /// <summary>
  252. /// Gets the column width for a given column index.
  253. /// </summary>
  254. /// <param name="index"></param>
  255. public Double GetColumnWidth(Int32 index)
  256. {
  257. List<Double> widths = ColumnWidths;
  258. if (widths == null || index > widths.Count - 1) return Double.NaN;
  259. return widths[index];
  260. }
  261. /// <summary>
  262. /// Sets the column width for the given index.
  263. /// </summary>
  264. /// <param name="index">Column index</param>
  265. /// <param name="width">Colum width</param>
  266. public void SetColumnWidth(Int32 index, Double width)
  267. {
  268. List<Double> widths = ColumnWidths;
  269. if (widths == null || index > widths.Count - 1)
  270. {
  271. if (Rows.Count == 0) throw new Exception("There is at least one row required to detect the existing columns.");
  272. // use width of last row cells
  273. // may not work for merged cell!
  274. widths = new List<Double>();
  275. foreach (Cell c in Rows[Rows.Count - 1].Cells)
  276. {
  277. widths.Add(c.Width);
  278. }
  279. }
  280. // check if index is matching table columns
  281. if (index > widths.Count - 1) throw new Exception("The index is greather than the available table columns.");
  282. // get the table grid props
  283. XElement grid = Xml.Element(XName.Get("tblGrid", DocX.w.NamespaceName));
  284. // if null; append a new grid below tblPr
  285. if (grid == null)
  286. {
  287. XElement tblPr = GetOrCreate_tblPr();
  288. tblPr.AddAfterSelf(new XElement(XName.Get("tblGrid", DocX.w.NamespaceName)));
  289. grid = Xml.Element(XName.Get("tblGrid", DocX.w.NamespaceName));
  290. }
  291. // remove all existing values
  292. grid.RemoveAll();
  293. // append new column widths
  294. XElement gridCol = null;
  295. Int32 i = 0;
  296. Double value = width;
  297. Double total = 0;
  298. foreach (var w in widths)
  299. {
  300. value = w;
  301. if (i == index) value = width;
  302. gridCol = new XElement(XName.Get("gridCol", DocX.w.NamespaceName),
  303. new XAttribute(XName.Get("w", DocX.w.NamespaceName), value));
  304. grid.Add(gridCol);
  305. i += 1;
  306. total += value;
  307. }
  308. // remove cell widths
  309. foreach (Row r in Rows)
  310. foreach (Cell c in r.Cells)
  311. c.Width = -1;
  312. // set fitting to fixed; this will add/set additional table properties
  313. this.AutoFit = AutoFit.Fixed;
  314. }
  315. /// <summary>
  316. /// Gets a list of all column widths for this table.
  317. /// </summary>
  318. public List<Double> ColumnWidths
  319. {
  320. get
  321. {
  322. List<Double> widths = new List<Double>();
  323. // get the table grid props
  324. XElement grid = Xml.Element(XName.Get("tblGrid", DocX.w.NamespaceName));
  325. if (grid == null) return null;
  326. // get col properties
  327. var cols = grid.Elements(XName.Get("gridCol", DocX.w.NamespaceName));
  328. if (cols == null) return null;
  329. String value = String.Empty;
  330. foreach (var col in cols)
  331. {
  332. value = col.GetAttribute(XName.Get("w", DocX.w.NamespaceName));
  333. widths.Add(Convert.ToDouble(value));
  334. }
  335. return widths;
  336. }
  337. }
  338. /// <summary>
  339. /// Returns the number of rows in this table.
  340. /// </summary>
  341. public Int32 RowCount
  342. {
  343. get
  344. {
  345. return Xml.Elements(XName.Get("tr", DocX.w.NamespaceName)).Count();
  346. }
  347. }
  348. private int _cachedColCount = -1;
  349. /// <summary>
  350. /// Returns the number of columns in this table.
  351. /// </summary>
  352. public Int32 ColumnCount
  353. {
  354. get
  355. {
  356. if (RowCount == 0)
  357. return 0;
  358. if (_cachedColCount == -1)
  359. _cachedColCount = Rows.First().ColumnCount;
  360. return _cachedColCount;
  361. }
  362. }
  363. /// <summary>
  364. /// Returns a list of rows in this table.
  365. /// </summary>
  366. public List<Row> Rows
  367. {
  368. get
  369. {
  370. List<Row> rows =
  371. (
  372. from r in Xml.Elements(XName.Get("tr", DocX.w.NamespaceName))
  373. select new Row(this, Document, r)
  374. ).ToList();
  375. return rows;
  376. }
  377. }
  378. private TableDesign design;
  379. internal Table(DocX document, XElement xml)
  380. : base(document, xml)
  381. {
  382. autofit = AutoFit.ColumnWidth;
  383. this.Xml = xml;
  384. this.mainPart = document.mainPart;
  385. XElement properties = xml.Element(XName.Get("tblPr", DocX.w.NamespaceName));
  386. XElement style = properties.Element(XName.Get("tblStyle", DocX.w.NamespaceName));
  387. if (style != null)
  388. {
  389. XAttribute val = style.Attribute(XName.Get("val", DocX.w.NamespaceName));
  390. if (val != null)
  391. {
  392. try
  393. {
  394. design = (TableDesign)Enum.Parse(typeof(TableDesign), val.Value.Replace("-", string.Empty));
  395. }
  396. catch (Exception)
  397. {
  398. design = TableDesign.Custom;
  399. }
  400. }
  401. else
  402. design = TableDesign.None;
  403. }
  404. else
  405. design = TableDesign.None;
  406. XElement tableLook = properties.Element(XName.Get("tblLook", DocX.w.NamespaceName));
  407. if (tableLook != null)
  408. {
  409. TableLook = new TableLook();
  410. TableLook.FirstRow = tableLook.GetAttribute(XName.Get("firstRow", DocX.w.NamespaceName)) == "1";
  411. TableLook.LastRow = tableLook.GetAttribute(XName.Get("lastRow", DocX.w.NamespaceName)) == "1";
  412. TableLook.FirstColumn = tableLook.GetAttribute(XName.Get("firstColumn", DocX.w.NamespaceName)) == "1";
  413. TableLook.LastColumn = tableLook.GetAttribute(XName.Get("lastColumn", DocX.w.NamespaceName)) == "1";
  414. TableLook.NoHorizontalBanding = tableLook.GetAttribute(XName.Get("noHBand", DocX.w.NamespaceName)) == "1";
  415. TableLook.NoVerticalBanding = tableLook.GetAttribute(XName.Get("noVBand", DocX.w.NamespaceName)) == "1";
  416. }
  417. }
  418. /// <summary>
  419. /// Extra property for Custom Table Style provided by carpfisher - Thanks
  420. /// </summary>
  421. private string _customTableDesignName;
  422. /// <summary>
  423. /// Extra property for Custom Table Style provided by carpfisher - Thanks
  424. /// </summary>
  425. public string CustomTableDesignName
  426. {
  427. set
  428. {
  429. _customTableDesignName = value;
  430. this.Design = TableDesign.Custom;
  431. }
  432. get
  433. {
  434. return _customTableDesignName;
  435. }
  436. }
  437. /// <summary>
  438. /// String containing the Table Caption value (the table's Alternate Text Title)
  439. /// </summary>
  440. private string _tableCaption;
  441. /// <summary>
  442. /// Gets or Sets the value of the Table Caption (Alternate Text Title) of this table.
  443. /// </summary>
  444. public string TableCaption
  445. {
  446. set
  447. {
  448. XElement tblPr = Xml.Element(XName.Get("tblPr", DocX.w.NamespaceName));
  449. if (tblPr != null)
  450. {
  451. XElement tblCaption =
  452. tblPr.Descendants(XName.Get("tblCaption", DocX.w.NamespaceName)).FirstOrDefault();
  453. if (tblCaption != null)
  454. tblCaption.Remove();
  455. tblCaption = new XElement(XName.Get("tblCaption", DocX.w.NamespaceName),
  456. new XAttribute(XName.Get("val", DocX.w.NamespaceName), value));
  457. tblPr.Add(tblCaption);
  458. }
  459. }
  460. get
  461. {
  462. XElement tblPr = Xml.Element(XName.Get("tblPr", DocX.w.NamespaceName));
  463. if (tblPr != null)
  464. {
  465. XElement caption = tblPr.Element(XName.Get("tblCaption", DocX.w.NamespaceName));
  466. if (caption != null)
  467. {
  468. _tableCaption = caption.GetAttribute(XName.Get("val", DocX.w.NamespaceName));
  469. }
  470. }
  471. return _tableCaption;
  472. }
  473. }
  474. /// <summary>
  475. /// String containing the Table Description (the table's Alternate Text Description).
  476. /// </summary>
  477. private string _tableDescription;
  478. /// <summary>
  479. /// Gets or Sets the value of the Table Description (Alternate Text Description) of this table.
  480. /// </summary>
  481. public string TableDescription
  482. {
  483. set
  484. {
  485. XElement tblPr = Xml.Element(XName.Get("tblPr", DocX.w.NamespaceName));
  486. if (tblPr != null)
  487. {
  488. XElement tblDescription =
  489. tblPr.Descendants(XName.Get("tblDescription", DocX.w.NamespaceName)).FirstOrDefault();
  490. if (tblDescription != null)
  491. tblDescription.Remove();
  492. tblDescription = new XElement(XName.Get("tblDescription", DocX.w.NamespaceName),
  493. new XAttribute(XName.Get("val", DocX.w.NamespaceName), value));
  494. tblPr.Add(tblDescription);
  495. }
  496. }
  497. get
  498. {
  499. XElement tblPr = Xml.Element(XName.Get("tblPr", DocX.w.NamespaceName));
  500. if (tblPr != null)
  501. {
  502. XElement caption = tblPr.Element(XName.Get("tblDescription", DocX.w.NamespaceName));
  503. if (caption != null)
  504. {
  505. _tableDescription = caption.GetAttribute(XName.Get("val", DocX.w.NamespaceName));
  506. }
  507. }
  508. return _tableDescription;
  509. }
  510. }
  511. public TableLook TableLook { get; set; }
  512. public Alignment Alignment
  513. {
  514. get { return alignment; }
  515. set
  516. {
  517. string alignmentString = string.Empty;
  518. switch (value)
  519. {
  520. case Alignment.left:
  521. {
  522. alignmentString = "left";
  523. break;
  524. }
  525. case Alignment.both:
  526. {
  527. alignmentString = "both";
  528. break;
  529. }
  530. case Alignment.right:
  531. {
  532. alignmentString = "right";
  533. break;
  534. }
  535. case Alignment.center:
  536. {
  537. alignmentString = "center";
  538. break;
  539. }
  540. }
  541. XElement tblPr = Xml.Descendants(XName.Get("tblPr", DocX.w.NamespaceName)).First();
  542. XElement jc = tblPr.Descendants(XName.Get("jc", DocX.w.NamespaceName)).FirstOrDefault();
  543. if (jc != null)
  544. jc.Remove();
  545. jc = new XElement(XName.Get("jc", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), alignmentString));
  546. tblPr.Add(jc);
  547. alignment = value;
  548. }
  549. }
  550. /// <summary>
  551. /// Auto size this table according to some rule.
  552. /// </summary>
  553. /// <remarks>Added by Roger Saele, April 2012. Thank you for your contribution Roger.</remarks>
  554. public AutoFit AutoFit
  555. {
  556. get { return autofit; }
  557. set
  558. {
  559. string tableAttributeValue = string.Empty;
  560. string columnAttributeValue = string.Empty;
  561. switch (value)
  562. {
  563. case AutoFit.ColumnWidth:
  564. {
  565. tableAttributeValue = "auto";
  566. columnAttributeValue = "dxa";
  567. // Disable "Automatically resize to fit contents" option
  568. XElement tblPr = Xml.Element(XName.Get("tblPr", DocX.w.NamespaceName));
  569. if (tblPr != null)
  570. {
  571. XElement layout = tblPr.Element(XName.Get("tblLayout", DocX.w.NamespaceName));
  572. if (layout == null)
  573. {
  574. tblPr.Add(new XElement(XName.Get("tblLayout", DocX.w.NamespaceName)));
  575. layout = tblPr.Element(XName.Get("tblLayout", DocX.w.NamespaceName));
  576. }
  577. XAttribute type = layout.Attribute(XName.Get("type", DocX.w.NamespaceName));
  578. if (type == null)
  579. {
  580. layout.Add(new XAttribute(XName.Get("type", DocX.w.NamespaceName), String.Empty));
  581. type = layout.Attribute(XName.Get("type", DocX.w.NamespaceName));
  582. }
  583. type.Value = "fixed";
  584. }
  585. break;
  586. }
  587. case AutoFit.Contents:
  588. {
  589. tableAttributeValue = columnAttributeValue = "auto";
  590. break;
  591. }
  592. case AutoFit.Window:
  593. {
  594. tableAttributeValue = columnAttributeValue = "pct";
  595. break;
  596. }
  597. case AutoFit.Fixed:
  598. // DL added - 20150816:
  599. // Set fixed width for the whole table; columns width is definied in the node: tblGrid
  600. {
  601. tableAttributeValue = columnAttributeValue = "dxa";
  602. XElement tblPr = Xml.Element(XName.Get("tblPr", DocX.w.NamespaceName));
  603. XElement tblLayout = tblPr.Element(XName.Get("tblLayout", DocX.w.NamespaceName));
  604. if (tblLayout == null)
  605. {
  606. XElement tmp = tblPr.Element(XName.Get("tblInd", DocX.w.NamespaceName));
  607. if (tmp == null)
  608. {
  609. tmp = tblPr.Element(XName.Get("tblW", DocX.w.NamespaceName));
  610. }
  611. tmp.AddAfterSelf(new XElement(XName.Get("tblLayout", DocX.w.NamespaceName)));
  612. tmp = tblPr.Element(XName.Get("tblLayout", DocX.w.NamespaceName));
  613. tmp.SetAttributeValue(XName.Get("type", DocX.w.NamespaceName), "fixed");
  614. tmp = tblPr.Element(XName.Get("tblW", DocX.w.NamespaceName));
  615. Double i = 0;
  616. foreach (Double w in ColumnWidths)
  617. i += w;
  618. tmp.SetAttributeValue(XName.Get("w", DocX.w.NamespaceName), i.ToString());
  619. break;
  620. }
  621. else
  622. {
  623. var qry = from d in Xml.Descendants()
  624. let type = d.Attribute(XName.Get("type", DocX.w.NamespaceName))
  625. where (d.Name.LocalName == "tblLayout") && type != null
  626. select type;
  627. foreach (XAttribute type in qry)
  628. type.Value = "fixed";
  629. XElement tmp = tblPr.Element(XName.Get("tblW", DocX.w.NamespaceName));
  630. Double i = 0;
  631. foreach (Double w in ColumnWidths)
  632. i += w;
  633. tmp.SetAttributeValue(XName.Get("w", DocX.w.NamespaceName), i.ToString());
  634. break;
  635. }
  636. }
  637. }
  638. // Set table attributes
  639. var query = from d in Xml.Descendants()
  640. let type = d.Attribute(XName.Get("type", DocX.w.NamespaceName))
  641. where (d.Name.LocalName == "tblW") && type != null
  642. select type;
  643. foreach (XAttribute type in query)
  644. type.Value = tableAttributeValue;
  645. // Set column attributes
  646. query = from d in Xml.Descendants()
  647. let type = d.Attribute(XName.Get("type", DocX.w.NamespaceName))
  648. where (d.Name.LocalName == "tcW") && type != null
  649. select type;
  650. foreach (XAttribute type in query)
  651. type.Value = columnAttributeValue;
  652. autofit = value;
  653. }
  654. }
  655. /// <summary>
  656. /// The design\style to apply to this table.
  657. ///
  658. /// Patch1. Patch to code for Custom Table Style support by carpfisher
  659. /// </summary>
  660. /// <example>
  661. /// Example code for custom table style usage
  662. ///
  663. /// <code>
  664. /// Novacode.DocX document = Novacode.DocX.Load(“DOC01.doc”); // load document with custom table style defined
  665. /// Novacode.Table t = document.AddTable(2, 2); // adds table
  666. /// t.CustomTableDesignName = “MyStyle01”; // assigns Custom Table Design style to newly created table
  667. /// </code>
  668. /// </example>
  669. ///
  670. ///
  671. ///
  672. public TableDesign Design
  673. {
  674. get { return design; }
  675. set
  676. {
  677. XElement tblPr = Xml.Element(XName.Get("tblPr", DocX.w.NamespaceName));
  678. XElement style = tblPr.Element(XName.Get("tblStyle", DocX.w.NamespaceName));
  679. if (style == null)
  680. {
  681. tblPr.Add(new XElement(XName.Get("tblStyle", DocX.w.NamespaceName)));
  682. style = tblPr.Element(XName.Get("tblStyle", DocX.w.NamespaceName));
  683. }
  684. XAttribute val = style.Attribute(XName.Get("val", DocX.w.NamespaceName));
  685. if (val == null)
  686. {
  687. style.Add(new XAttribute(XName.Get("val", DocX.w.NamespaceName), ""));
  688. val = style.Attribute(XName.Get("val", DocX.w.NamespaceName));
  689. }
  690. design = value;
  691. if (design == TableDesign.None)
  692. {
  693. if (style != null)
  694. style.Remove();
  695. }
  696. if (design == TableDesign.Custom)
  697. {
  698. if (string.IsNullOrEmpty(_customTableDesignName))
  699. {
  700. design = TableDesign.None;
  701. if (style != null)
  702. style.Remove();
  703. }
  704. else
  705. {
  706. val.Value = _customTableDesignName;
  707. }
  708. }
  709. else
  710. {
  711. switch (design)
  712. {
  713. case TableDesign.TableNormal:
  714. val.Value = "TableNormal";
  715. break;
  716. case TableDesign.TableGrid:
  717. val.Value = "TableGrid";
  718. break;
  719. case TableDesign.LightShading:
  720. val.Value = "LightShading";
  721. break;
  722. case TableDesign.LightShadingAccent1:
  723. val.Value = "LightShading-Accent1";
  724. break;
  725. case TableDesign.LightShadingAccent2:
  726. val.Value = "LightShading-Accent2";
  727. break;
  728. case TableDesign.LightShadingAccent3:
  729. val.Value = "LightShading-Accent3";
  730. break;
  731. case TableDesign.LightShadingAccent4:
  732. val.Value = "LightShading-Accent4";
  733. break;
  734. case TableDesign.LightShadingAccent5:
  735. val.Value = "LightShading-Accent5";
  736. break;
  737. case TableDesign.LightShadingAccent6:
  738. val.Value = "LightShading-Accent6";
  739. break;
  740. case TableDesign.LightList:
  741. val.Value = "LightList";
  742. break;
  743. case TableDesign.LightListAccent1:
  744. val.Value = "LightList-Accent1";
  745. break;
  746. case TableDesign.LightListAccent2:
  747. val.Value = "LightList-Accent2";
  748. break;
  749. case TableDesign.LightListAccent3:
  750. val.Value = "LightList-Accent3";
  751. break;
  752. case TableDesign.LightListAccent4:
  753. val.Value = "LightList-Accent4";
  754. break;
  755. case TableDesign.LightListAccent5:
  756. val.Value = "LightList-Accent5";
  757. break;
  758. case TableDesign.LightListAccent6:
  759. val.Value = "LightList-Accent6";
  760. break;
  761. case TableDesign.LightGrid:
  762. val.Value = "LightGrid";
  763. break;
  764. case TableDesign.LightGridAccent1:
  765. val.Value = "LightGrid-Accent1";
  766. break;
  767. case TableDesign.LightGridAccent2:
  768. val.Value = "LightGrid-Accent2";
  769. break;
  770. case TableDesign.LightGridAccent3:
  771. val.Value = "LightGrid-Accent3";
  772. break;
  773. case TableDesign.LightGridAccent4:
  774. val.Value = "LightGrid-Accent4";
  775. break;
  776. case TableDesign.LightGridAccent5:
  777. val.Value = "LightGrid-Accent5";
  778. break;
  779. case TableDesign.LightGridAccent6:
  780. val.Value = "LightGrid-Accent6";
  781. break;
  782. case TableDesign.MediumShading1:
  783. val.Value = "MediumShading1";
  784. break;
  785. case TableDesign.MediumShading1Accent1:
  786. val.Value = "MediumShading1-Accent1";
  787. break;
  788. case TableDesign.MediumShading1Accent2:
  789. val.Value = "MediumShading1-Accent2";
  790. break;
  791. case TableDesign.MediumShading1Accent3:
  792. val.Value = "MediumShading1-Accent3";
  793. break;
  794. case TableDesign.MediumShading1Accent4:
  795. val.Value = "MediumShading1-Accent4";
  796. break;
  797. case TableDesign.MediumShading1Accent5:
  798. val.Value = "MediumShading1-Accent5";
  799. break;
  800. case TableDesign.MediumShading1Accent6:
  801. val.Value = "MediumShading1-Accent6";
  802. break;
  803. case TableDesign.MediumShading2:
  804. val.Value = "MediumShading2";
  805. break;
  806. case TableDesign.MediumShading2Accent1:
  807. val.Value = "MediumShading2-Accent1";
  808. break;
  809. case TableDesign.MediumShading2Accent2:
  810. val.Value = "MediumShading2-Accent2";
  811. break;
  812. case TableDesign.MediumShading2Accent3:
  813. val.Value = "MediumShading2-Accent3";
  814. break;
  815. case TableDesign.MediumShading2Accent4:
  816. val.Value = "MediumShading2-Accent4";
  817. break;
  818. case TableDesign.MediumShading2Accent5:
  819. val.Value = "MediumShading2-Accent5";
  820. break;
  821. case TableDesign.MediumShading2Accent6:
  822. val.Value = "MediumShading2-Accent6";
  823. break;
  824. case TableDesign.MediumList1:
  825. val.Value = "MediumList1";
  826. break;
  827. case TableDesign.MediumList1Accent1:
  828. val.Value = "MediumList1-Accent1";
  829. break;
  830. case TableDesign.MediumList1Accent2:
  831. val.Value = "MediumList1-Accent2";
  832. break;
  833. case TableDesign.MediumList1Accent3:
  834. val.Value = "MediumList1-Accent3";
  835. break;
  836. case TableDesign.MediumList1Accent4:
  837. val.Value = "MediumList1-Accent4";
  838. break;
  839. case TableDesign.MediumList1Accent5:
  840. val.Value = "MediumList1-Accent5";
  841. break;
  842. case TableDesign.MediumList1Accent6:
  843. val.Value = "MediumList1-Accent6";
  844. break;
  845. case TableDesign.MediumList2:
  846. val.Value = "MediumList2";
  847. break;
  848. case TableDesign.MediumList2Accent1:
  849. val.Value = "MediumList2-Accent1";
  850. break;
  851. case TableDesign.MediumList2Accent2:
  852. val.Value = "MediumList2-Accent2";
  853. break;
  854. case TableDesign.MediumList2Accent3:
  855. val.Value = "MediumList2-Accent3";
  856. break;
  857. case TableDesign.MediumList2Accent4:
  858. val.Value = "MediumList2-Accent4";
  859. break;
  860. case TableDesign.MediumList2Accent5:
  861. val.Value = "MediumList2-Accent5";
  862. break;
  863. case TableDesign.MediumList2Accent6:
  864. val.Value = "MediumList2-Accent6";
  865. break;
  866. case TableDesign.MediumGrid1:
  867. val.Value = "MediumGrid1";
  868. break;
  869. case TableDesign.MediumGrid1Accent1:
  870. val.Value = "MediumGrid1-Accent1";
  871. break;
  872. case TableDesign.MediumGrid1Accent2:
  873. val.Value = "MediumGrid1-Accent2";
  874. break;
  875. case TableDesign.MediumGrid1Accent3:
  876. val.Value = "MediumGrid1-Accent3";
  877. break;
  878. case TableDesign.MediumGrid1Accent4:
  879. val.Value = "MediumGrid1-Accent4";
  880. break;
  881. case TableDesign.MediumGrid1Accent5:
  882. val.Value = "MediumGrid1-Accent5";
  883. break;
  884. case TableDesign.MediumGrid1Accent6:
  885. val.Value = "MediumGrid1-Accent6";
  886. break;
  887. case TableDesign.MediumGrid2:
  888. val.Value = "MediumGrid2";
  889. break;
  890. case TableDesign.MediumGrid2Accent1:
  891. val.Value = "MediumGrid2-Accent1";
  892. break;
  893. case TableDesign.MediumGrid2Accent2:
  894. val.Value = "MediumGrid2-Accent2";
  895. break;
  896. case TableDesign.MediumGrid2Accent3:
  897. val.Value = "MediumGrid2-Accent3";
  898. break;
  899. case TableDesign.MediumGrid2Accent4:
  900. val.Value = "MediumGrid2-Accent4";
  901. break;
  902. case TableDesign.MediumGrid2Accent5:
  903. val.Value = "MediumGrid2-Accent5";
  904. break;
  905. case TableDesign.MediumGrid2Accent6:
  906. val.Value = "MediumGrid2-Accent6";
  907. break;
  908. case TableDesign.MediumGrid3:
  909. val.Value = "MediumGrid3";
  910. break;
  911. case TableDesign.MediumGrid3Accent1:
  912. val.Value = "MediumGrid3-Accent1";
  913. break;
  914. case TableDesign.MediumGrid3Accent2:
  915. val.Value = "MediumGrid3-Accent2";
  916. break;
  917. case TableDesign.MediumGrid3Accent3:
  918. val.Value = "MediumGrid3-Accent3";
  919. break;
  920. case TableDesign.MediumGrid3Accent4:
  921. val.Value = "MediumGrid3-Accent4";
  922. break;
  923. case TableDesign.MediumGrid3Accent5:
  924. val.Value = "MediumGrid3-Accent5";
  925. break;
  926. case TableDesign.MediumGrid3Accent6:
  927. val.Value = "MediumGrid3-Accent6";
  928. break;
  929. case TableDesign.DarkList:
  930. val.Value = "DarkList";
  931. break;
  932. case TableDesign.DarkListAccent1:
  933. val.Value = "DarkList-Accent1";
  934. break;
  935. case TableDesign.DarkListAccent2:
  936. val.Value = "DarkList-Accent2";
  937. break;
  938. case TableDesign.DarkListAccent3:
  939. val.Value = "DarkList-Accent3";
  940. break;
  941. case TableDesign.DarkListAccent4:
  942. val.Value = "DarkList-Accent4";
  943. break;
  944. case TableDesign.DarkListAccent5:
  945. val.Value = "DarkList-Accent5";
  946. break;
  947. case TableDesign.DarkListAccent6:
  948. val.Value = "DarkList-Accent6";
  949. break;
  950. case TableDesign.ColorfulShading:
  951. val.Value = "ColorfulShading";
  952. break;
  953. case TableDesign.ColorfulShadingAccent1:
  954. val.Value = "ColorfulShading-Accent1";
  955. break;
  956. case TableDesign.ColorfulShadingAccent2:
  957. val.Value = "ColorfulShading-Accent2";
  958. break;
  959. case TableDesign.ColorfulShadingAccent3:
  960. val.Value = "ColorfulShading-Accent3";
  961. break;
  962. case TableDesign.ColorfulShadingAccent4:
  963. val.Value = "ColorfulShading-Accent4";
  964. break;
  965. case TableDesign.ColorfulShadingAccent5:
  966. val.Value = "ColorfulShading-Accent5";
  967. break;
  968. case TableDesign.ColorfulShadingAccent6:
  969. val.Value = "ColorfulShading-Accent6";
  970. break;
  971. case TableDesign.ColorfulList:
  972. val.Value = "ColorfulList";
  973. break;
  974. case TableDesign.ColorfulListAccent1:
  975. val.Value = "ColorfulList-Accent1";
  976. break;
  977. case TableDesign.ColorfulListAccent2:
  978. val.Value = "ColorfulList-Accent2";
  979. break;
  980. case TableDesign.ColorfulListAccent3:
  981. val.Value = "ColorfulList-Accent3";
  982. break;
  983. case TableDesign.ColorfulListAccent4:
  984. val.Value = "ColorfulList-Accent4";
  985. break;
  986. case TableDesign.ColorfulListAccent5:
  987. val.Value = "ColorfulList-Accent5";
  988. break;
  989. case TableDesign.ColorfulListAccent6:
  990. val.Value = "ColorfulList-Accent6";
  991. break;
  992. case TableDesign.ColorfulGrid:
  993. val.Value = "ColorfulGrid";
  994. break;
  995. case TableDesign.ColorfulGridAccent1:
  996. val.Value = "ColorfulGrid-Accent1";
  997. break;
  998. case TableDesign.ColorfulGridAccent2:
  999. val.Value = "ColorfulGrid-Accent2";
  1000. break;
  1001. case TableDesign.ColorfulGridAccent3:
  1002. val.Value = "ColorfulGrid-Accent3";
  1003. break;
  1004. case TableDesign.ColorfulGridAccent4:
  1005. val.Value = "ColorfulGrid-Accent4";
  1006. break;
  1007. case TableDesign.ColorfulGridAccent5:
  1008. val.Value = "ColorfulGrid-Accent5";
  1009. break;
  1010. case TableDesign.ColorfulGridAccent6:
  1011. val.Value = "ColorfulGrid-Accent6";
  1012. break;
  1013. default:
  1014. break;
  1015. }
  1016. }
  1017. if (Document.styles == null)
  1018. {
  1019. PackagePart word_styles = Document.package.GetPart(new Uri("/word/styles.xml", UriKind.Relative));
  1020. using (TextReader tr = new StreamReader(word_styles.GetStream()))
  1021. Document.styles = XDocument.Load(tr);
  1022. }
  1023. var tableStyle =
  1024. (
  1025. from e in Document.styles.Descendants()
  1026. let styleId = e.Attribute(XName.Get("styleId", DocX.w.NamespaceName))
  1027. where (styleId != null && styleId.Value == val.Value)
  1028. select e
  1029. ).FirstOrDefault();
  1030. if (tableStyle == null)
  1031. {
  1032. XDocument external_style_doc = HelperFunctions.DecompressXMLResource("Novacode.Resources.styles.xml.gz");
  1033. var styleElement =
  1034. (
  1035. from e in external_style_doc.Descendants()
  1036. let styleId = e.Attribute(XName.Get("styleId", DocX.w.NamespaceName))
  1037. where (styleId != null && styleId.Value == val.Value)
  1038. select e
  1039. ).First();
  1040. Document.styles.Element(XName.Get("styles", DocX.w.NamespaceName)).Add(styleElement);
  1041. }
  1042. }
  1043. }
  1044. /// <summary>
  1045. /// Returns the index of this Table.
  1046. /// </summary>
  1047. /// <example>
  1048. /// Replace the first table in this document with a new Table.
  1049. /// <code>
  1050. /// // Load a document into memory.
  1051. /// using (DocX document = DocX.Load(@"Test.docx"))
  1052. /// {
  1053. /// // Get the first Table in this document.
  1054. /// Table t = document.Tables[0];
  1055. ///
  1056. /// // Get the character index of Table t in this document.
  1057. /// int index = t.Index;
  1058. ///
  1059. /// // Remove Table t.
  1060. /// t.Remove();
  1061. ///
  1062. /// // Insert a new Table at the original index of Table t.
  1063. /// Table newTable = document.InsertTable(index, 4, 4);
  1064. ///
  1065. /// // Set the design of this new Table, so that we can see it.
  1066. /// newTable.Design = TableDesign.LightShadingAccent1;
  1067. ///
  1068. /// // Save all changes made to the document.
  1069. /// document.Save();
  1070. /// } // Release this document from memory.
  1071. /// </code>
  1072. /// </example>
  1073. public int Index
  1074. {
  1075. get
  1076. {
  1077. int index = 0;
  1078. IEnumerable<XElement> previous = Xml.ElementsBeforeSelf();
  1079. foreach (XElement e in previous)
  1080. index += Paragraph.GetElementTextLength(e);
  1081. return index;
  1082. }
  1083. }
  1084. /// <summary>
  1085. /// Remove this Table from this document.
  1086. /// </summary>
  1087. /// <example>
  1088. /// Remove the first Table from this document.
  1089. /// <code>
  1090. /// // Load a document into memory.
  1091. /// using (DocX document = DocX.Load(@"Test.docx"))
  1092. /// {
  1093. /// // Get the first Table in this document.
  1094. /// Table t = d.Tables[0];
  1095. ///
  1096. /// // Remove this Table.
  1097. /// t.Remove();
  1098. ///
  1099. /// // Save all changes made to the document.
  1100. /// document.Save();
  1101. /// } // Release this document from memory.
  1102. /// </code>
  1103. /// </example>
  1104. public void Remove()
  1105. {
  1106. Xml.Remove();
  1107. }
  1108. /// <summary>
  1109. /// Insert a row at the end of this table.
  1110. /// </summary>
  1111. /// <example>
  1112. /// <code>
  1113. /// // Load a document.
  1114. /// using (DocX document = DocX.Load(@"C:\Example\Test.docx"))
  1115. /// {
  1116. /// // Get the first table in this document.
  1117. /// Table table = document.Tables[0];
  1118. ///
  1119. /// // Insert a new row at the end of this table.
  1120. /// Row row = table.InsertRow();
  1121. ///
  1122. /// // Loop through each cell in this new row.
  1123. /// foreach (Cell c in row.Cells)
  1124. /// {
  1125. /// // Set the text of each new cell to "Hello".
  1126. /// c.Paragraphs[0].InsertText("Hello", false);
  1127. /// }
  1128. ///
  1129. /// // Save the document to a new file.
  1130. /// document.SaveAs(@"C:\Example\Test2.docx");
  1131. /// }// Release this document from memory.
  1132. /// </code>
  1133. /// </example>
  1134. /// <returns>A new row.</returns>
  1135. public Row InsertRow()
  1136. {
  1137. return InsertRow(RowCount);
  1138. }
  1139. /// <summary>
  1140. /// Insert a copy of a row at the end of this table.
  1141. /// </summary>
  1142. /// <returns>A new row.</returns>
  1143. public Row InsertRow(Row row)
  1144. {
  1145. return InsertRow(row, RowCount);
  1146. }
  1147. /// <summary>
  1148. /// Insert a column to the right of a Table.
  1149. /// </summary>
  1150. /// <example>
  1151. /// <code>
  1152. /// // Load a document.
  1153. /// using (DocX document = DocX.Load(@"C:\Example\Test.docx"))
  1154. /// {
  1155. /// // Get the first Table in this document.
  1156. /// Table table = document.Tables[0];
  1157. ///
  1158. /// // Insert a new column to this right of this table.
  1159. /// table.InsertColumn();
  1160. ///
  1161. /// // Set the new columns text to "Row no."
  1162. /// table.Rows[0].Cells[table.ColumnCount - 1].Paragraph.InsertText("Row no.", false);
  1163. ///
  1164. /// // Loop through each row in the table.
  1165. /// for (int i = 1; i &lt; table.Rows.Count; i++)
  1166. /// {
  1167. /// // The current row.
  1168. /// Row row = table.Rows[i];
  1169. ///
  1170. /// // The cell in this row that belongs to the new column.
  1171. /// Cell cell = row.Cells[table.ColumnCount - 1];
  1172. ///
  1173. /// // The first Paragraph that this cell houses.
  1174. /// Paragraph p = cell.Paragraphs[0];
  1175. ///
  1176. /// // Insert this rows index.
  1177. /// p.InsertText(i.ToString(), false);
  1178. /// }
  1179. ///
  1180. /// document.Save();
  1181. /// }// Release this document from memory.
  1182. /// </code>
  1183. /// </example>
  1184. public void InsertColumn()
  1185. {
  1186. InsertColumn(ColumnCount, true);
  1187. }
  1188. /// <summary>
  1189. /// Remove the last row from this Table.
  1190. /// </summary>
  1191. /// <example>
  1192. /// Remove the last row from a Table.
  1193. /// <code>
  1194. /// // Load a document.
  1195. /// using (DocX document = DocX.Load(@"C:\Example\Test.docx"))
  1196. /// {
  1197. /// // Get the first table in this document.
  1198. /// Table table = document.Tables[0];
  1199. ///
  1200. /// // Remove the last row from this table.
  1201. /// table.RemoveRow();
  1202. ///
  1203. /// // Save the document.
  1204. /// document.Save();
  1205. /// }// Release this document from memory.
  1206. /// </code>
  1207. /// </example>
  1208. public void RemoveRow()
  1209. {
  1210. RemoveRow(RowCount - 1);
  1211. }
  1212. /// <summary>
  1213. /// Remove a row from this Table.
  1214. /// </summary>
  1215. /// <param name="index">The row to remove.</param>
  1216. /// <example>
  1217. /// Remove the first row from a Table.
  1218. /// <code>
  1219. /// // Load a document.
  1220. /// using (DocX document = DocX.Load(@"C:\Example\Test.docx"))
  1221. /// {
  1222. /// // Get the first table in this document.
  1223. /// Table table = document.Tables[0];
  1224. ///
  1225. /// // Remove the first row from this table.
  1226. /// table.RemoveRow(0);
  1227. ///
  1228. /// // Save the document.
  1229. /// document.Save();
  1230. /// }// Release this document from memory.
  1231. /// </code>
  1232. /// </example>
  1233. public void RemoveRow(int index)
  1234. {
  1235. if (index < 0 || index > RowCount - 1)
  1236. throw new IndexOutOfRangeException();
  1237. Rows[index].Xml.Remove();
  1238. if (Rows.Count == 0)
  1239. Remove();
  1240. }
  1241. /// <summary>
  1242. /// Remove the last column for this Table.
  1243. /// </summary>
  1244. /// <example>
  1245. /// Remove the last column from a Table.
  1246. /// <code>
  1247. /// // Load a document.
  1248. /// using (DocX document = DocX.Load(@"C:\Example\Test.docx"))
  1249. /// {
  1250. /// // Get the first table in this document.
  1251. /// Table table = document.Tables[0];
  1252. ///
  1253. /// // Remove the last column from this table.
  1254. /// table.RemoveColumn();
  1255. ///
  1256. /// // Save the document.
  1257. /// document.Save();
  1258. /// }// Release this document from memory.
  1259. /// </code>
  1260. /// </example>
  1261. public void RemoveColumn()
  1262. {
  1263. RemoveColumn(ColumnCount - 1);
  1264. }
  1265. /// <summary>
  1266. /// Remove a column from this Table.
  1267. /// </summary>
  1268. /// <param name="index">The column to remove.</param>
  1269. /// <example>
  1270. /// Remove the first column from a Table.
  1271. /// <code>
  1272. /// // Load a document.
  1273. /// using (DocX document = DocX.Load(@"C:\Example\Test.docx"))
  1274. /// {
  1275. /// // Get the first table in this document.
  1276. /// Table table = document.Tables[0];
  1277. ///
  1278. /// // Remove the first column from this table.
  1279. /// table.RemoveColumn(0);
  1280. ///
  1281. /// // Save the document.
  1282. /// document.Save();
  1283. /// }// Release this document from memory.
  1284. /// </code>
  1285. /// </example>
  1286. public void RemoveColumn(int index)
  1287. {
  1288. if (index < 0 || index > ColumnCount - 1)
  1289. throw new IndexOutOfRangeException();
  1290. foreach (Row r in Rows)
  1291. r.Cells[index].Xml.Remove();
  1292. _cachedColCount = -1;
  1293. }
  1294. /// <summary>
  1295. /// Insert a row into this table.
  1296. /// </summary>
  1297. /// <example>
  1298. /// <code>
  1299. /// // Load a document.
  1300. /// using (DocX document = DocX.Load(@"C:\Example\Test.docx"))
  1301. /// {
  1302. /// // Get the first table in this document.
  1303. /// Table table = document.Tables[0];
  1304. ///
  1305. /// // Insert a new row at index 1 in this table.
  1306. /// Row row = table.InsertRow(1);
  1307. ///
  1308. /// // Loop through each cell in this new row.
  1309. /// foreach (Cell c in row.Cells)
  1310. /// {
  1311. /// // Set the text of each new cell to "Hello".
  1312. /// c.Paragraphs[0].InsertText("Hello", false);
  1313. /// }
  1314. ///
  1315. /// // Save the document to a new file.
  1316. /// document.SaveAs(@"C:\Example\Test2.docx");
  1317. /// }// Release this document from memory.
  1318. /// </code>
  1319. /// </example>
  1320. /// <param name="index">Index to insert row at.</param>
  1321. /// <returns>A new Row</returns>
  1322. public Row InsertRow(int index)
  1323. {
  1324. if (index < 0 || index > RowCount)
  1325. throw new IndexOutOfRangeException();
  1326. List<XElement> content = new List<XElement>();
  1327. for (int i = 0; i < ColumnCount; i++)
  1328. {
  1329. var w = 2310d;
  1330. if (ColumnWidthsValue != null && ColumnWidthsValue.Length > i)
  1331. w = ColumnWidthsValue[i] * 15;
  1332. XElement cell = HelperFunctions.CreateTableCell(w);
  1333. content.Add(cell);
  1334. }
  1335. return InsertRow(content, index);
  1336. }
  1337. /// <summary>
  1338. /// Insert a copy of a row into this table.
  1339. /// </summary>
  1340. /// <param name="row">Row to copy and insert.</param>
  1341. /// <param name="index">Index to insert row at.</param>
  1342. /// <returns>A new Row</returns>
  1343. public Row InsertRow(Row row, int index)
  1344. {
  1345. if (row == null)
  1346. throw new ArgumentNullException("row");
  1347. if (index < 0 || index > RowCount)
  1348. throw new IndexOutOfRangeException();
  1349. List<XElement> content = row.Xml.Elements(XName.Get("tc", DocX.w.NamespaceName)).Select(element => HelperFunctions.CloneElement(element)).ToList();
  1350. return InsertRow(content, index);
  1351. }
  1352. private Row InsertRow(List<XElement> content, Int32 index)
  1353. {
  1354. Row newRow = new Row(this, Document, new XElement(XName.Get("tr", DocX.w.NamespaceName), content));
  1355. XElement rowXml;
  1356. if (index == Rows.Count)
  1357. {
  1358. rowXml = Rows.Last().Xml;
  1359. rowXml.AddAfterSelf(newRow.Xml);
  1360. }
  1361. else
  1362. {
  1363. rowXml = Rows[index].Xml;
  1364. rowXml.AddBeforeSelf(newRow.Xml);
  1365. }
  1366. return newRow;
  1367. }
  1368. /// <summary>
  1369. /// Insert a column into a table.
  1370. /// </summary>
  1371. /// <param name="index">The index to insert the column at.</param>
  1372. /// <param name="direction">The side in which you wish to place the colum(True right, false left)</param>
  1373. /// <example>
  1374. /// Insert a column to the left of a table.
  1375. /// <code>
  1376. /// // Load a document.
  1377. /// using (DocX document = DocX.Load(@"C:\Example\Test.docx"))
  1378. /// {
  1379. /// // Get the first Table in this document.
  1380. /// Table table = document.Tables[0];
  1381. ///
  1382. /// // Insert a new column to this left of this table.
  1383. /// table.InsertColumn(0, false);
  1384. ///
  1385. /// // Set the new columns text to "Row no."
  1386. /// table.Rows[0].Cells[table.ColumnCount - 1].Paragraph.InsertText("Row no.", false);
  1387. ///
  1388. /// // Loop through each row in the table.
  1389. /// for (int i = 1; i &lt; table.Rows.Count; i++)
  1390. /// {
  1391. /// // The current row.
  1392. /// Row row = table.Rows[i];
  1393. ///
  1394. /// // The cell in this row that belongs to the new column.
  1395. /// Cell cell = row.Cells[table.ColumnCount - 1];
  1396. ///
  1397. /// // The first Paragraph that this cell houses.
  1398. /// Paragraph p = cell.Paragraphs[0];
  1399. ///
  1400. /// // Insert this rows index.
  1401. /// p.InsertText(i.ToString(), false);
  1402. /// }
  1403. ///
  1404. /// document.Save();
  1405. /// }// Release this document from memory.
  1406. /// </code>
  1407. /// </example>
  1408. public void InsertColumn(int index, bool direction)
  1409. {
  1410. var columnCount = ColumnCount;
  1411. if (RowCount > 0)
  1412. {
  1413. if (index > 0 && index <= columnCount)
  1414. {
  1415. _cachedColCount = -1;
  1416. foreach (Row r in Rows)
  1417. {
  1418. // create cell
  1419. XElement cell = HelperFunctions.CreateTableCell();
  1420. // insert cell
  1421. // checks if it is in bounds of index
  1422. // TODO: Check for gridspan of cells in row to check if merged cells
  1423. if (r.Cells.Count < columnCount)
  1424. {
  1425. if (index >= columnCount)
  1426. {
  1427. AddCellToRow(r, cell, r.Cells.Count, direction);
  1428. }
  1429. else
  1430. {
  1431. bool directionTest = true;
  1432. var positionIndex = 1;
  1433. var actualPosition = 1;
  1434. var gridAfterVal = 0;
  1435. // checks to see if here is a deleted cell
  1436. XElement trPr = r.Xml.Element(XName.Get("trPr", DocX.w.NamespaceName));
  1437. if (trPr != null)
  1438. {
  1439. XElement gridAfter = trPr.Element(XName.Get("gridAfter", DocX.w.NamespaceName));
  1440. if (gridAfter != null)
  1441. {
  1442. XAttribute val = gridAfter.Attribute(XName.Get("val", DocX.w.NamespaceName));
  1443. if (val != null)
  1444. {
  1445. gridAfterVal = int.Parse(val.Value);
  1446. }
  1447. }
  1448. }
  1449. // goes through iteration of cells to find the one the that contains the index number
  1450. foreach (Cell rowCell in r.Cells)
  1451. {
  1452. var gridSpanVal = 0;
  1453. XElement tcPr = rowCell.Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  1454. if (tcPr != null)
  1455. {
  1456. XElement gridSpan = tcPr.Element(XName.Get("gridSpan", DocX.w.NamespaceName));
  1457. if (gridSpan != null)
  1458. {
  1459. XAttribute val = gridSpan.Attribute(XName.Get("val", DocX.w.NamespaceName));
  1460. int value = 0;
  1461. if (val != null)
  1462. if (int.TryParse(val.Value, out value))
  1463. gridSpanVal = value -1;
  1464. }
  1465. }
  1466. // Sees if the cell has gridSpan and if the index is within its lowest and highest cell value
  1467. if ((index - gridAfterVal) >= actualPosition
  1468. && (index - gridAfterVal) <= (actualPosition + gridSpanVal))
  1469. {
  1470. if (index == (actualPosition + gridSpanVal) && direction == true)
  1471. {
  1472. directionTest = true;
  1473. }
  1474. else
  1475. {
  1476. directionTest = false;
  1477. }
  1478. AddCellToRow(r, cell, positionIndex, directionTest);
  1479. break;
  1480. }
  1481. positionIndex += 1;
  1482. actualPosition += gridSpanVal + 1;
  1483. }
  1484. }
  1485. }
  1486. else if (r.Cells.Count == index)
  1487. {
  1488. AddCellToRow(r, cell, index, direction);
  1489. }
  1490. else
  1491. AddCellToRow(r, cell, index, direction);
  1492. }
  1493. }
  1494. else
  1495. {
  1496. throw new IndexOutOfRangeException("Out of index bounds, column count is " + columnCount + " you input " + index);
  1497. }
  1498. }
  1499. }
  1500. /// <summary>
  1501. /// Adds a cell to the right or left of a cell
  1502. /// </summary>
  1503. /// <param name="row">is the row you are adding</param>
  1504. /// <param name="cell">is the cell you are adding</param>
  1505. /// <param name="index">the cell index position you are refferencing from</param>
  1506. /// <param name="direction">which side of the cell you wish to add cell</param>
  1507. private void AddCellToRow(Row row, XElement cell, int index, bool direction)
  1508. {
  1509. index -= 1;
  1510. if (direction)
  1511. {
  1512. row.Cells[index].Xml.AddAfterSelf(cell);
  1513. }
  1514. else
  1515. {
  1516. row.Cells[index].Xml.AddBeforeSelf(cell);
  1517. }
  1518. }
  1519. public void DeleteAndShiftCellsLeft(int rowIndex, int celIndex)
  1520. {
  1521. XAttribute gridAfterVal = new XAttribute(XName.Get("val", DocX.w.NamespaceName), 0);
  1522. var trPr = Rows[rowIndex].Xml.Element(XName.Get("trPr", DocX.w.NamespaceName));
  1523. if (trPr != null)
  1524. {
  1525. var gridAfter = trPr.Element(XName.Get("gridAfter", DocX.w.NamespaceName));
  1526. if (gridAfter != null)
  1527. {
  1528. var val = gridAfter.Attribute(XName.Get("val", DocX.w.NamespaceName));
  1529. if (val != null)
  1530. {
  1531. val.Value = int.Parse(val.Value + 1).ToString();
  1532. }
  1533. else
  1534. {
  1535. val.Value = "1";
  1536. }
  1537. }
  1538. else
  1539. {
  1540. var gridAfterElement = new XElement("gridAfter");
  1541. var gridAfterValAttribute = new XAttribute("val", 1);
  1542. gridAfter.SetAttributeValue("val", 1);
  1543. }
  1544. }
  1545. else
  1546. {
  1547. XElement trPrXElement = new XElement(XName.Get("trPr",DocX.w.NamespaceName));
  1548. XElement gridAfterElement = new XElement(XName.Get("gridAfter", DocX.w.NamespaceName));
  1549. XAttribute gridAfterValAttribute = new XAttribute(XName.Get("val", DocX.w.NamespaceName), 1);
  1550. gridAfterElement.Add(gridAfterValAttribute);
  1551. trPrXElement.Add(gridAfterElement);
  1552. Rows[rowIndex].Xml.AddFirst(trPrXElement);
  1553. }
  1554. var columnCount = this.ColumnCount;
  1555. if (celIndex <= this.ColumnCount && this.Rows[rowIndex].ColumnCount <= this.ColumnCount)
  1556. {
  1557. Rows[rowIndex].Cells[celIndex].Xml.Remove();
  1558. }
  1559. }
  1560. /// <summary>
  1561. /// Insert a page break before a Table.
  1562. /// </summary>
  1563. /// <example>
  1564. /// Insert a Table and a Paragraph into a document with a page break between them.
  1565. /// <code>
  1566. /// // Create a new document.
  1567. /// using (DocX document = DocX.Create(@"Test.docx"))
  1568. /// {
  1569. /// // Insert a new Paragraph.
  1570. /// Paragraph p1 = document.InsertParagraph("Paragraph", false);
  1571. ///
  1572. /// // Insert a new Table.
  1573. /// Table t1 = document.InsertTable(2, 2);
  1574. /// t1.Design = TableDesign.LightShadingAccent1;
  1575. ///
  1576. /// // Insert a page break before this Table.
  1577. /// t1.InsertPageBreakBeforeSelf();
  1578. ///
  1579. /// // Save this document.
  1580. /// document.Save();
  1581. /// }// Release this document from memory.
  1582. /// </code>
  1583. /// </example>
  1584. public override void InsertPageBreakBeforeSelf()
  1585. {
  1586. base.InsertPageBreakBeforeSelf();
  1587. }
  1588. /// <summary>
  1589. /// Insert a page break after a Table.
  1590. /// </summary>
  1591. /// <example>
  1592. /// Insert a Table and a Paragraph into a document with a page break between them.
  1593. /// <code>
  1594. /// // Create a new document.
  1595. /// using (DocX document = DocX.Create(@"Test.docx"))
  1596. /// {
  1597. /// // Insert a new Table.
  1598. /// Table t1 = document.InsertTable(2, 2);
  1599. /// t1.Design = TableDesign.LightShadingAccent1;
  1600. ///
  1601. /// // Insert a page break after this Table.
  1602. /// t1.InsertPageBreakAfterSelf();
  1603. ///
  1604. /// // Insert a new Paragraph.
  1605. /// Paragraph p1 = document.InsertParagraph("Paragraph", false);
  1606. ///
  1607. /// // Save this document.
  1608. /// document.Save();
  1609. /// }// Release this document from memory.
  1610. /// </code>
  1611. /// </example>
  1612. public override void InsertPageBreakAfterSelf()
  1613. {
  1614. base.InsertPageBreakAfterSelf();
  1615. }
  1616. /// <summary>
  1617. /// Insert a new Table before this Table, this Table can be from this document or another document.
  1618. /// </summary>
  1619. /// <param name="t">The Table t to be inserted</param>
  1620. /// <returns>A new Table inserted before this Table.</returns>
  1621. /// <example>
  1622. /// Insert a new Table before this Table.
  1623. /// <code>
  1624. /// // Place holder for a Table.
  1625. /// Table t;
  1626. ///
  1627. /// // Load document a.
  1628. /// using (DocX documentA = DocX.Load(@"a.docx"))
  1629. /// {
  1630. /// // Get the first Table from this document.
  1631. /// t = documentA.Tables[0];
  1632. /// }
  1633. ///
  1634. /// // Load document b.
  1635. /// using (DocX documentB = DocX.Load(@"b.docx"))
  1636. /// {
  1637. /// // Get the first Table in document b.
  1638. /// Table t2 = documentB.Tables[0];
  1639. ///
  1640. /// // Insert the Table from document a before this Table.
  1641. /// Table newTable = t2.InsertTableBeforeSelf(t);
  1642. ///
  1643. /// // Save all changes made to document b.
  1644. /// documentB.Save();
  1645. /// }// Release this document from memory.
  1646. /// </code>
  1647. /// </example>
  1648. public override Table InsertTableBeforeSelf(Table t)
  1649. {
  1650. return base.InsertTableBeforeSelf(t);
  1651. }
  1652. /// <summary>
  1653. /// Insert a new Table into this document before this Table.
  1654. /// </summary>
  1655. /// <param name="rowCount">The number of rows this Table should have.</param>
  1656. /// <param name="columnCount">The number of columns this Table should have.</param>
  1657. /// <returns>A new Table inserted before this Table.</returns>
  1658. /// <example>
  1659. /// <code>
  1660. /// // Create a new document.
  1661. /// using (DocX document = DocX.Create(@"Test.docx"))
  1662. /// {
  1663. /// //Insert a Table into this document.
  1664. /// Table t = document.InsertTable(2, 2);
  1665. /// t.Design = TableDesign.LightShadingAccent1;
  1666. /// t.Alignment = Alignment.center;
  1667. ///
  1668. /// // Insert a new Table before this Table.
  1669. /// Table newTable = t.InsertTableBeforeSelf(2, 2);
  1670. /// newTable.Design = TableDesign.LightShadingAccent2;
  1671. /// newTable.Alignment = Alignment.center;
  1672. ///
  1673. /// // Save all changes made to this document.
  1674. /// document.Save();
  1675. /// }// Release this document from memory.
  1676. /// </code>
  1677. /// </example>
  1678. public override Table InsertTableBeforeSelf(int rowCount, int columnCount)
  1679. {
  1680. return base.InsertTableBeforeSelf(rowCount, columnCount);
  1681. }
  1682. /// <summary>
  1683. /// Insert a new Table after this Table, this Table can be from this document or another document.
  1684. /// </summary>
  1685. /// <param name="t">The Table t to be inserted</param>
  1686. /// <returns>A new Table inserted after this Table.</returns>
  1687. /// <example>
  1688. /// Insert a new Table after this Table.
  1689. /// <code>
  1690. /// // Place holder for a Table.
  1691. /// Table t;
  1692. ///
  1693. /// // Load document a.
  1694. /// using (DocX documentA = DocX.Load(@"a.docx"))
  1695. /// {
  1696. /// // Get the first Table from this document.
  1697. /// t = documentA.Tables[0];
  1698. /// }
  1699. ///
  1700. /// // Load document b.
  1701. /// using (DocX documentB = DocX.Load(@"b.docx"))
  1702. /// {
  1703. /// // Get the first Table in document b.
  1704. /// Table t2 = documentB.Tables[0];
  1705. ///
  1706. /// // Insert the Table from document a after this Table.
  1707. /// Table newTable = t2.InsertTableAfterSelf(t);
  1708. ///
  1709. /// // Save all changes made to document b.
  1710. /// documentB.Save();
  1711. /// }// Release this document from memory.
  1712. /// </code>
  1713. /// </example>
  1714. public override Table InsertTableAfterSelf(Table t)
  1715. {
  1716. return base.InsertTableAfterSelf(t);
  1717. }
  1718. /// <summary>
  1719. /// Insert a new Table into this document after this Table.
  1720. /// </summary>
  1721. /// <param name="rowCount">The number of rows this Table should have.</param>
  1722. /// <param name="columnCount">The number of columns this Table should have.</param>
  1723. /// <returns>A new Table inserted before this Table.</returns>
  1724. /// <example>
  1725. /// <code>
  1726. /// // Create a new document.
  1727. /// using (DocX document = DocX.Create(@"Test.docx"))
  1728. /// {
  1729. /// //Insert a Table into this document.
  1730. /// Table t = document.InsertTable(2, 2);
  1731. /// t.Design = TableDesign.LightShadingAccent1;
  1732. /// t.Alignment = Alignment.center;
  1733. ///
  1734. /// // Insert a new Table after this Table.
  1735. /// Table newTable = t.InsertTableAfterSelf(2, 2);
  1736. /// newTable.Design = TableDesign.LightShadingAccent2;
  1737. /// newTable.Alignment = Alignment.center;
  1738. ///
  1739. /// // Save all changes made to this document.
  1740. /// document.Save();
  1741. /// }// Release this document from memory.
  1742. /// </code>
  1743. /// </example>
  1744. public override Table InsertTableAfterSelf(int rowCount, int columnCount)
  1745. {
  1746. return base.InsertTableAfterSelf(rowCount, columnCount);
  1747. }
  1748. /// <summary>
  1749. /// Insert a Paragraph before this Table, this Paragraph may have come from the same or another document.
  1750. /// </summary>
  1751. /// <param name="p">The Paragraph to insert.</param>
  1752. /// <returns>The Paragraph now associated with this document.</returns>
  1753. /// <example>
  1754. /// Take a Paragraph from document a, and insert it into document b before this Table.
  1755. /// <code>
  1756. /// // Place holder for a Paragraph.
  1757. /// Paragraph p;
  1758. ///
  1759. /// // Load document a.
  1760. /// using (DocX documentA = DocX.Load(@"a.docx"))
  1761. /// {
  1762. /// // Get the first paragraph from this document.
  1763. /// p = documentA.Paragraphs[0];
  1764. /// }
  1765. ///
  1766. /// // Load document b.
  1767. /// using (DocX documentB = DocX.Load(@"b.docx"))
  1768. /// {
  1769. /// // Get the first Table in document b.
  1770. /// Table t = documentB.Tables[0];
  1771. ///
  1772. /// // Insert the Paragraph from document a before this Table.
  1773. /// Paragraph newParagraph = t.InsertParagraphBeforeSelf(p);
  1774. ///
  1775. /// // Save all changes made to document b.
  1776. /// documentB.Save();
  1777. /// }// Release this document from memory.
  1778. /// </code>
  1779. /// </example>
  1780. public override Paragraph InsertParagraphBeforeSelf(Paragraph p)
  1781. {
  1782. return base.InsertParagraphBeforeSelf(p);
  1783. }
  1784. /// <summary>
  1785. /// Insert a new Paragraph before this Table.
  1786. /// </summary>
  1787. /// <param name="text">The initial text for this new Paragraph.</param>
  1788. /// <returns>A new Paragraph inserted before this Table.</returns>
  1789. /// <example>
  1790. /// Insert a new Paragraph before the first Table in this document.
  1791. /// <code>
  1792. /// // Create a new document.
  1793. /// using (DocX document = DocX.Create(@"Test.docx"))
  1794. /// {
  1795. /// // Insert a Table into this document.
  1796. /// Table t = document.InsertTable(2, 2);
  1797. ///
  1798. /// t.InsertParagraphBeforeSelf("I was inserted before the next Table.");
  1799. ///
  1800. /// // Save all changes made to this new document.
  1801. /// document.Save();
  1802. /// }// Release this new document form memory.
  1803. /// </code>
  1804. /// </example>
  1805. public override Paragraph InsertParagraphBeforeSelf(string text)
  1806. {
  1807. return base.InsertParagraphBeforeSelf(text);
  1808. }
  1809. /// <summary>
  1810. /// Insert a new Paragraph before this Table.
  1811. /// </summary>
  1812. /// <param name="text">The initial text for this new Paragraph.</param>
  1813. /// <param name="trackChanges">Should this insertion be tracked as a change?</param>
  1814. /// <returns>A new Paragraph inserted before this Table.</returns>
  1815. /// <example>
  1816. /// Insert a new paragraph before the first Table in this document.
  1817. /// <code>
  1818. /// // Create a new document.
  1819. /// using (DocX document = DocX.Create(@"Test.docx"))
  1820. /// {
  1821. /// // Insert a Table into this document.
  1822. /// Table t = document.InsertTable(2, 2);
  1823. ///
  1824. /// t.InsertParagraphBeforeSelf("I was inserted before the next Table.", false);
  1825. ///
  1826. /// // Save all changes made to this new document.
  1827. /// document.Save();
  1828. /// }// Release this new document form memory.
  1829. /// </code>
  1830. /// </example>
  1831. public override Paragraph InsertParagraphBeforeSelf(string text, bool trackChanges)
  1832. {
  1833. return base.InsertParagraphBeforeSelf(text, trackChanges);
  1834. }
  1835. /// <summary>
  1836. /// Insert a new Paragraph before this Table.
  1837. /// </summary>
  1838. /// <param name="text">The initial text for this new Paragraph.</param>
  1839. /// <param name="trackChanges">Should this insertion be tracked as a change?</param>
  1840. /// <param name="formatting">The formatting to apply to this insertion.</param>
  1841. /// <returns>A new Paragraph inserted before this Table.</returns>
  1842. /// <example>
  1843. /// Insert a new paragraph before the first Table in this document.
  1844. /// <code>
  1845. /// // Create a new document.
  1846. /// using (DocX document = DocX.Create(@"Test.docx"))
  1847. /// {
  1848. /// // Insert a Table into this document.
  1849. /// Table t = document.InsertTable(2, 2);
  1850. ///
  1851. /// Formatting boldFormatting = new Formatting();
  1852. /// boldFormatting.Bold = true;
  1853. ///
  1854. /// t.InsertParagraphBeforeSelf("I was inserted before the next Table.", false, boldFormatting);
  1855. ///
  1856. /// // Save all changes made to this new document.
  1857. /// document.Save();
  1858. /// }// Release this new document form memory.
  1859. /// </code>
  1860. /// </example>
  1861. public override Paragraph InsertParagraphBeforeSelf(string text, bool trackChanges, Formatting formatting)
  1862. {
  1863. return base.InsertParagraphBeforeSelf(text, trackChanges, formatting);
  1864. }
  1865. /// <summary>
  1866. /// Insert a Paragraph after this Table, this Paragraph may have come from the same or another document.
  1867. /// </summary>
  1868. /// <param name="p">The Paragraph to insert.</param>
  1869. /// <returns>The Paragraph now associated with this document.</returns>
  1870. /// <example>
  1871. /// Take a Paragraph from document a, and insert it into document b after this Table.
  1872. /// <code>
  1873. /// // Place holder for a Paragraph.
  1874. /// Paragraph p;
  1875. ///
  1876. /// // Load document a.
  1877. /// using (DocX documentA = DocX.Load(@"a.docx"))
  1878. /// {
  1879. /// // Get the first paragraph from this document.
  1880. /// p = documentA.Paragraphs[0];
  1881. /// }
  1882. ///
  1883. /// // Load document b.
  1884. /// using (DocX documentB = DocX.Load(@"b.docx"))
  1885. /// {
  1886. /// // Get the first Table in document b.
  1887. /// Table t = documentB.Tables[0];
  1888. ///
  1889. /// // Insert the Paragraph from document a after this Table.
  1890. /// Paragraph newParagraph = t.InsertParagraphAfterSelf(p);
  1891. ///
  1892. /// // Save all changes made to document b.
  1893. /// documentB.Save();
  1894. /// }// Release this document from memory.
  1895. /// </code>
  1896. /// </example>
  1897. public override Paragraph InsertParagraphAfterSelf(Paragraph p)
  1898. {
  1899. return base.InsertParagraphAfterSelf(p);
  1900. }
  1901. /// <summary>
  1902. /// Insert a new Paragraph after this Table.
  1903. /// </summary>
  1904. /// <param name="text">The initial text for this new Paragraph.</param>
  1905. /// <param name="trackChanges">Should this insertion be tracked as a change?</param>
  1906. /// <param name="formatting">The formatting to apply to this insertion.</param>
  1907. /// <returns>A new Paragraph inserted after this Table.</returns>
  1908. /// <example>
  1909. /// Insert a new paragraph after the first Table in this document.
  1910. /// <code>
  1911. /// // Create a new document.
  1912. /// using (DocX document = DocX.Create(@"Test.docx"))
  1913. /// {
  1914. /// // Insert a Table into this document.
  1915. /// Table t = document.InsertTable(2, 2);
  1916. ///
  1917. /// Formatting boldFormatting = new Formatting();
  1918. /// boldFormatting.Bold = true;
  1919. ///
  1920. /// t.InsertParagraphAfterSelf("I was inserted after the previous Table.", false, boldFormatting);
  1921. ///
  1922. /// // Save all changes made to this new document.
  1923. /// document.Save();
  1924. /// }// Release this new document form memory.
  1925. /// </code>
  1926. /// </example>
  1927. public override Paragraph InsertParagraphAfterSelf(string text, bool trackChanges, Formatting formatting)
  1928. {
  1929. return base.InsertParagraphAfterSelf(text, trackChanges, formatting);
  1930. }
  1931. /// <summary>
  1932. /// Insert a new Paragraph after this Table.
  1933. /// </summary>
  1934. /// <param name="text">The initial text for this new Paragraph.</param>
  1935. /// <param name="trackChanges">Should this insertion be tracked as a change?</param>
  1936. /// <returns>A new Paragraph inserted after this Table.</returns>
  1937. /// <example>
  1938. /// Insert a new paragraph after the first Table in this document.
  1939. /// <code>
  1940. /// // Create a new document.
  1941. /// using (DocX document = DocX.Create(@"Test.docx"))
  1942. /// {
  1943. /// // Insert a Table into this document.
  1944. /// Table t = document.InsertTable(2, 2);
  1945. ///
  1946. /// t.InsertParagraphAfterSelf("I was inserted after the previous Table.", false);
  1947. ///
  1948. /// // Save all changes made to this new document.
  1949. /// document.Save();
  1950. /// }// Release this new document form memory.
  1951. /// </code>
  1952. /// </example>
  1953. public override Paragraph InsertParagraphAfterSelf(string text, bool trackChanges)
  1954. {
  1955. return base.InsertParagraphAfterSelf(text, trackChanges);
  1956. }
  1957. /// <summary>
  1958. /// Insert a new Paragraph after this Table.
  1959. /// </summary>
  1960. /// <param name="text">The initial text for this new Paragraph.</param>
  1961. /// <returns>A new Paragraph inserted after this Table.</returns>
  1962. /// <example>
  1963. /// Insert a new Paragraph after the first Table in this document.
  1964. /// <code>
  1965. /// // Create a new document.
  1966. /// using (DocX document = DocX.Create(@"Test.docx"))
  1967. /// {
  1968. /// // Insert a Table into this document.
  1969. /// Table t = document.InsertTable(2, 2);
  1970. ///
  1971. /// t.InsertParagraphAfterSelf("I was inserted after the previous Table.");
  1972. ///
  1973. /// // Save all changes made to this new document.
  1974. /// document.Save();
  1975. /// }// Release this new document form memory.
  1976. /// </code>
  1977. /// </example>
  1978. public override Paragraph InsertParagraphAfterSelf(string text)
  1979. {
  1980. return base.InsertParagraphAfterSelf(text);
  1981. }
  1982. /// <summary>
  1983. /// Set a table border
  1984. /// Added by lckuiper @ 20101117
  1985. /// </summary>
  1986. /// <example>
  1987. /// <code>
  1988. /// // Create a new document.
  1989. ///using (DocX document = DocX.Create("Test.docx"))
  1990. ///{
  1991. /// // Insert a table into this document.
  1992. /// Table t = document.InsertTable(3, 3);
  1993. ///
  1994. /// // Create a large blue border.
  1995. /// Border b = new Border(BorderStyle.Tcbs_single, BorderSize.seven, 0, Color.Blue);
  1996. ///
  1997. /// // Set the tables Top, Bottom, Left and Right Borders to b.
  1998. /// t.SetBorder(TableBorderType.Top, b);
  1999. /// t.SetBorder(TableBorderType.Bottom, b);
  2000. /// t.SetBorder(TableBorderType.Left, b);
  2001. /// t.SetBorder(TableBorderType.Right, b);
  2002. ///
  2003. /// // Save the document.
  2004. /// document.Save();
  2005. ///}
  2006. /// </code>
  2007. /// </example>
  2008. /// <param name="borderType">The table border to set</param>
  2009. /// <param name="border">Border object to set the table border</param>
  2010. public void SetBorder(TableBorderType borderType, Border border)
  2011. {
  2012. /*
  2013. * Get the tblPr (table properties) element for this Table,
  2014. * null will be return if no such element exists.
  2015. */
  2016. XElement tblPr = Xml.Element(XName.Get("tblPr", DocX.w.NamespaceName));
  2017. if (tblPr == null)
  2018. {
  2019. Xml.SetElementValue(XName.Get("tblPr", DocX.w.NamespaceName), string.Empty);
  2020. tblPr = Xml.Element(XName.Get("tblPr", DocX.w.NamespaceName));
  2021. }
  2022. /*
  2023. * Get the tblBorders (table borders) element for this Table,
  2024. * null will be return if no such element exists.
  2025. */
  2026. XElement tblBorders = tblPr.Element(XName.Get("tblBorders", DocX.w.NamespaceName));
  2027. if (tblBorders == null)
  2028. {
  2029. tblPr.SetElementValue(XName.Get("tblBorders", DocX.w.NamespaceName), string.Empty);
  2030. tblBorders = tblPr.Element(XName.Get("tblBorders", DocX.w.NamespaceName));
  2031. }
  2032. /*
  2033. * Get the 'borderType' (table border) element for this Table,
  2034. * null will be return if no such element exists.
  2035. */
  2036. string tbordertype;
  2037. tbordertype = borderType.ToString();
  2038. // only lower the first char of string (because of insideH and insideV)
  2039. tbordertype = tbordertype.Substring(0, 1).ToLower() + tbordertype.Substring(1);
  2040. XElement tblBorderType = tblBorders.Element(XName.Get(borderType.ToString(), DocX.w.NamespaceName));
  2041. if (tblBorderType == null)
  2042. {
  2043. tblBorders.SetElementValue(XName.Get(tbordertype, DocX.w.NamespaceName), string.Empty);
  2044. tblBorderType = tblBorders.Element(XName.Get(tbordertype, DocX.w.NamespaceName));
  2045. }
  2046. // get string value of border style
  2047. string borderstyle = border.Tcbs.ToString().Substring(5);
  2048. borderstyle = borderstyle.Substring(0, 1).ToLower() + borderstyle.Substring(1);
  2049. // The val attribute is used for the border style
  2050. tblBorderType.SetAttributeValue(XName.Get("val", DocX.w.NamespaceName), borderstyle);
  2051. if (border.Tcbs != BorderStyle.Tcbs_nil)
  2052. {
  2053. int size;
  2054. switch (border.Size)
  2055. {
  2056. case BorderSize.one: size = 2; break;
  2057. case BorderSize.two: size = 4; break;
  2058. case BorderSize.three: size = 6; break;
  2059. case BorderSize.four: size = 8; break;
  2060. case BorderSize.five: size = 12; break;
  2061. case BorderSize.six: size = 18; break;
  2062. case BorderSize.seven: size = 24; break;
  2063. case BorderSize.eight: size = 36; break;
  2064. case BorderSize.nine: size = 48; break;
  2065. default: size = 2; break;
  2066. }
  2067. // The sz attribute is used for the border size
  2068. tblBorderType.SetAttributeValue(XName.Get("sz", DocX.w.NamespaceName), (size).ToString());
  2069. // The space attribute is used for the cell spacing (probably '0')
  2070. tblBorderType.SetAttributeValue(XName.Get("space", DocX.w.NamespaceName), (border.Space).ToString());
  2071. // The color attribute is used for the border color
  2072. tblBorderType.SetAttributeValue(XName.Get("color", DocX.w.NamespaceName), border.Color.ToHex());
  2073. }
  2074. }
  2075. /// <summary>
  2076. /// Get a table border
  2077. /// Added by lckuiper @ 20101117
  2078. /// </summary>
  2079. /// <param name="borderType">The table border to get</param>
  2080. public Border GetBorder(TableBorderType borderType)
  2081. {
  2082. // instance with default border values
  2083. Border b = new Border();
  2084. /*
  2085. * Get the tblPr (table properties) element for this Table,
  2086. * null will be return if no such element exists.
  2087. */
  2088. XElement tblPr = Xml.Element(XName.Get("tblPr", DocX.w.NamespaceName));
  2089. if (tblPr == null)
  2090. {
  2091. // uses default border style
  2092. }
  2093. /*
  2094. * Get the tblBorders (table borders) element for this Table,
  2095. * null will be return if no such element exists.
  2096. */
  2097. XElement tblBorders = tblPr.Element(XName.Get("tblBorders", DocX.w.NamespaceName));
  2098. if (tblBorders == null)
  2099. {
  2100. // uses default border style
  2101. }
  2102. /*
  2103. * Get the 'borderType' (table border) element for this Table,
  2104. * null will be return if no such element exists.
  2105. */
  2106. string tbordertype;
  2107. tbordertype = borderType.ToString();
  2108. // only lower the first char of string (because of insideH and insideV)
  2109. tbordertype = tbordertype.Substring(0, 1).ToLower() + tbordertype.Substring(1);
  2110. XElement tblBorderType = tblBorders.Element(XName.Get(tbordertype, DocX.w.NamespaceName));
  2111. if (tblBorderType == null)
  2112. {
  2113. // uses default border style
  2114. }
  2115. // The val attribute is used for the border style
  2116. XAttribute val = tblBorderType.Attribute(XName.Get("val", DocX.w.NamespaceName));
  2117. // If val is null, this table contains no border information.
  2118. if (val == null)
  2119. {
  2120. // uses default border style
  2121. }
  2122. else
  2123. {
  2124. try
  2125. {
  2126. string bordertype = "Tcbs_" + val.Value;
  2127. b.Tcbs = (BorderStyle)Enum.Parse(typeof(BorderStyle), bordertype);
  2128. }
  2129. catch
  2130. {
  2131. val.Remove();
  2132. // uses default border style
  2133. }
  2134. }
  2135. // The sz attribute is used for the border size
  2136. XAttribute sz = tblBorderType.Attribute(XName.Get("sz", DocX.w.NamespaceName));
  2137. // If sz is null, this border contains no size information.
  2138. if (sz == null)
  2139. {
  2140. // uses default border style
  2141. }
  2142. else
  2143. {
  2144. // If sz is not an int, something is wrong with this attributes value, so remove it
  2145. int numerical_size;
  2146. if (!int.TryParse(sz.Value, out numerical_size))
  2147. sz.Remove();
  2148. else
  2149. {
  2150. switch (numerical_size)
  2151. {
  2152. case 2: b.Size = BorderSize.one; break;
  2153. case 4: b.Size = BorderSize.two; break;
  2154. case 6: b.Size = BorderSize.three; break;
  2155. case 8: b.Size = BorderSize.four; break;
  2156. case 12: b.Size = BorderSize.five; break;
  2157. case 18: b.Size = BorderSize.six; break;
  2158. case 24: b.Size = BorderSize.seven; break;
  2159. case 36: b.Size = BorderSize.eight; break;
  2160. case 48: b.Size = BorderSize.nine; break;
  2161. default: b.Size = BorderSize.one; break;
  2162. }
  2163. }
  2164. }
  2165. // The space attribute is used for the border spacing (probably '0')
  2166. XAttribute space = tblBorderType.Attribute(XName.Get("space", DocX.w.NamespaceName));
  2167. // If space is null, this border contains no space information.
  2168. if (space == null)
  2169. {
  2170. // uses default border style
  2171. }
  2172. else
  2173. {
  2174. // If space is not an int, something is wrong with this attributes value, so remove it
  2175. int borderspace;
  2176. if (!int.TryParse(space.Value, out borderspace))
  2177. {
  2178. space.Remove();
  2179. // uses default border style
  2180. }
  2181. else
  2182. {
  2183. b.Space = borderspace;
  2184. }
  2185. }
  2186. // The color attribute is used for the border color
  2187. XAttribute color = tblBorderType.Attribute(XName.Get("color", DocX.w.NamespaceName));
  2188. if (color == null)
  2189. {
  2190. // uses default border style
  2191. }
  2192. else
  2193. {
  2194. // If color is not a Color, something is wrong with this attributes value, so remove it
  2195. try
  2196. {
  2197. b.Color = ColorTranslator.FromHtml(string.Format("#{0}", color.Value));
  2198. }
  2199. catch
  2200. {
  2201. color.Remove();
  2202. // uses default border style
  2203. }
  2204. }
  2205. return b;
  2206. }
  2207. }
  2208. /// <summary>
  2209. /// Represents a single row in a Table.
  2210. /// </summary>
  2211. public class Row : Container
  2212. {
  2213. /// <summary>
  2214. /// Calculates columns count in the row, taking spanned cells into account
  2215. /// </summary>
  2216. public Int32 ColumnCount
  2217. {
  2218. get
  2219. {
  2220. int gridSpanSum = 0;
  2221. var trPr = Xml.Element(XName.Get("trPr",DocX.w.NamespaceName));
  2222. if(trPr !=null)
  2223. {
  2224. var gridAfter = trPr.Element(XName.Get("gridAfter", DocX.w.NamespaceName));
  2225. if(gridAfter != null)
  2226. {
  2227. var val = gridAfter.Attribute(XName.Get("val", DocX.w.NamespaceName));
  2228. if(val != null)
  2229. {
  2230. gridSpanSum += int.Parse(val.Value);
  2231. }
  2232. }
  2233. }
  2234. // Foreach each Cell between startIndex and endIndex inclusive.
  2235. foreach (Cell c in Cells)
  2236. {
  2237. XElement tcPr = c.Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  2238. if (tcPr != null)
  2239. {
  2240. XElement gridSpan = tcPr.Element(XName.Get("gridSpan", DocX.w.NamespaceName));
  2241. if (gridSpan != null)
  2242. {
  2243. XAttribute val = gridSpan.Attribute(XName.Get("val", DocX.w.NamespaceName));
  2244. int value = 0;
  2245. if (val != null)
  2246. if (int.TryParse(val.Value, out value))
  2247. gridSpanSum += value - 1;
  2248. }
  2249. }
  2250. }
  2251. // return cells count + count of spanned cells
  2252. return Cells.Count + gridSpanSum;
  2253. }
  2254. }
  2255. /// <summary>
  2256. /// A list of Cells in this Row.
  2257. /// </summary>
  2258. public List<Cell> Cells
  2259. {
  2260. get
  2261. {
  2262. List<Cell> cells =
  2263. (
  2264. from c in Xml.Elements(XName.Get("tc", DocX.w.NamespaceName))
  2265. select new Cell(this, Document, c)
  2266. ).ToList();
  2267. return cells;
  2268. }
  2269. }
  2270. public void Remove()
  2271. {
  2272. XElement table = Xml.Parent;
  2273. Xml.Remove();
  2274. if (table.Elements(XName.Get("tr", DocX.w.NamespaceName)).Count() == 0)
  2275. table.Remove();
  2276. }
  2277. public override ReadOnlyCollection<Paragraph> Paragraphs
  2278. {
  2279. get
  2280. {
  2281. List<Paragraph> paragraphs =
  2282. (
  2283. from p in Xml.Descendants(DocX.w + "p")
  2284. select new Paragraph(Document, p, 0)
  2285. ).ToList();
  2286. foreach (Paragraph p in paragraphs)
  2287. p.PackagePart = table.mainPart;
  2288. return paragraphs.AsReadOnly();
  2289. }
  2290. }
  2291. internal Table table;
  2292. internal Row(Table table, DocX document, XElement xml)
  2293. : base(document, xml)
  2294. {
  2295. this.table = table;
  2296. this.mainPart = table.mainPart;
  2297. }
  2298. /// <summary>
  2299. /// The property name to set when specifiying an exact height
  2300. /// </summary>
  2301. /// <created>Nick Kusters</created>
  2302. const string _hRule_Exact = "exact";
  2303. /// <summary>
  2304. /// The property name to set when specifying a minimum height
  2305. /// </summary>
  2306. /// <created>Nick Kusters</created>
  2307. const string _hRule_AtLeast = "atLeast";
  2308. /// <summary>
  2309. /// Height in pixels. // Added by Joel, refactored by Cathal.
  2310. /// </summary>
  2311. public double Height
  2312. {
  2313. get
  2314. {
  2315. /*
  2316. * Get the trPr (table row properties) element for this Row,
  2317. * null will be return if no such element exists.
  2318. */
  2319. XElement trPr = Xml.Element(XName.Get("trPr", DocX.w.NamespaceName));
  2320. // If trPr is null, this row contains no height information.
  2321. if (trPr == null)
  2322. return double.NaN;
  2323. /*
  2324. * Get the trHeight element for this Row,
  2325. * null will be return if no such element exists.
  2326. */
  2327. XElement trHeight = trPr.Element(XName.Get("trHeight", DocX.w.NamespaceName));
  2328. // If trHeight is null, this row contains no height information.
  2329. if (trHeight == null)
  2330. return double.NaN;
  2331. // Get the val attribute for this trHeight element.
  2332. XAttribute val = trHeight.Attribute(XName.Get("val", DocX.w.NamespaceName));
  2333. // If w is null, this cell contains no width information.
  2334. if (val == null)
  2335. return double.NaN;
  2336. // If val is not a double, something is wrong with this attributes value, so remove it and return double.NaN;
  2337. double heightInWordUnits;
  2338. if (!double.TryParse(val.Value, out heightInWordUnits))
  2339. {
  2340. val.Remove();
  2341. return double.NaN;
  2342. }
  2343. // 15 "word units" in one pixel
  2344. return (heightInWordUnits / 15);
  2345. }
  2346. set
  2347. {
  2348. SetHeight(value, true);
  2349. }
  2350. }
  2351. /// <summary>
  2352. /// Helper method to set either the exact height or the min-height
  2353. /// </summary>
  2354. /// <param name="height">The height value to set (in pixels)</param>
  2355. /// <param name="exact">
  2356. /// If true, the height will be forced.
  2357. /// If false, it will be treated as a minimum height, auto growing past it if need be.
  2358. /// </param>
  2359. /// <created>Nick Kusters</created>
  2360. void SetHeight(double height, bool exact)
  2361. {
  2362. /*
  2363. * Get the trPr (table row properties) element for this Row,
  2364. * null will be return if no such element exists.
  2365. */
  2366. XElement trPr = Xml.Element(XName.Get("trPr", DocX.w.NamespaceName));
  2367. if (trPr == null)
  2368. {
  2369. Xml.SetElementValue(XName.Get("trPr", DocX.w.NamespaceName), string.Empty);
  2370. trPr = Xml.Element(XName.Get("trPr", DocX.w.NamespaceName));
  2371. }
  2372. /*
  2373. * Get the trHeight element for this Row,
  2374. * null will be return if no such element exists.
  2375. */
  2376. XElement trHeight = trPr.Element(XName.Get("trHeight", DocX.w.NamespaceName));
  2377. if (trHeight == null)
  2378. {
  2379. trPr.SetElementValue(XName.Get("trHeight", DocX.w.NamespaceName), string.Empty);
  2380. trHeight = trPr.Element(XName.Get("trHeight", DocX.w.NamespaceName));
  2381. }
  2382. // The hRule attribute needs to be set to exact.
  2383. trHeight.SetAttributeValue(XName.Get("hRule", DocX.w.NamespaceName), exact ? _hRule_Exact : _hRule_AtLeast);
  2384. // 15 "word units" is equal to one pixel.
  2385. trHeight.SetAttributeValue(XName.Get("val", DocX.w.NamespaceName), (height * 15).ToString());
  2386. }
  2387. /// <summary>
  2388. /// Min-Height in pixels. // Added by Nick Kusters.
  2389. /// </summary>
  2390. /// <remarks>
  2391. /// Value will be treated as a minimum height, auto growing past it if need be.
  2392. /// </remarks>
  2393. /// <created>Nick Kusters</created>
  2394. public double MinHeight
  2395. {
  2396. get
  2397. {
  2398. // Just return the value from the normal height property since it doesn't care if you've set an exact or minimum height.
  2399. return Height;
  2400. }
  2401. set
  2402. {
  2403. SetHeight(value, false);
  2404. }
  2405. }
  2406. /// <summary>
  2407. /// Set to true to make this row the table header row that will be repeated on each page
  2408. /// </summary>
  2409. public bool TableHeader
  2410. {
  2411. get
  2412. {
  2413. XElement trPr = Xml.Element(XName.Get("trPr", DocX.w.NamespaceName));
  2414. XElement tblHeader = trPr.Element(XName.Get("tblHeader", DocX.w.NamespaceName));
  2415. if (tblHeader == null)
  2416. {
  2417. return false;
  2418. }
  2419. else
  2420. {
  2421. return true;
  2422. }
  2423. }
  2424. set
  2425. {
  2426. XElement trPr = Xml.Element(XName.Get("trPr", DocX.w.NamespaceName));
  2427. if (trPr == null)
  2428. {
  2429. Xml.SetElementValue(XName.Get("trPr", DocX.w.NamespaceName), string.Empty);
  2430. trPr = Xml.Element(XName.Get("trPr", DocX.w.NamespaceName));
  2431. }
  2432. XElement tblHeader = trPr.Element(XName.Get("tblHeader", DocX.w.NamespaceName));
  2433. if (tblHeader == null && value)
  2434. {
  2435. trPr.SetElementValue(XName.Get("tblHeader", DocX.w.NamespaceName), string.Empty);
  2436. }
  2437. if (tblHeader != null && !value)
  2438. {
  2439. tblHeader.Remove();
  2440. }
  2441. }
  2442. }
  2443. /// <summary>
  2444. /// Allow row to break across pages.
  2445. /// The default value is true: Word will break the contents of the row across pages.
  2446. /// If set to false, the contents of the row will not be split across pages, the entire row will be moved to the next page instead.
  2447. /// </summary>
  2448. public bool BreakAcrossPages
  2449. {
  2450. get
  2451. {
  2452. XElement trPr = Xml.Element(XName.Get("trPr", DocX.w.NamespaceName));
  2453. if (trPr == null)
  2454. return true;
  2455. XElement trCantSplit = trPr.Element(XName.Get("cantSplit", DocX.w.NamespaceName));
  2456. if (trCantSplit == null)
  2457. return true;
  2458. return false;
  2459. }
  2460. set
  2461. {
  2462. if (value == false)
  2463. {
  2464. XElement trPr = Xml.Element(XName.Get("trPr", DocX.w.NamespaceName));
  2465. if (trPr == null)
  2466. {
  2467. Xml.SetElementValue(XName.Get("trPr", DocX.w.NamespaceName), string.Empty);
  2468. trPr = Xml.Element(XName.Get("trPr", DocX.w.NamespaceName));
  2469. }
  2470. XElement trCantSplit = trPr.Element(XName.Get("cantSplit", DocX.w.NamespaceName));
  2471. if (trCantSplit == null)
  2472. trPr.SetElementValue(XName.Get("cantSplit", DocX.w.NamespaceName), string.Empty);
  2473. }
  2474. if (value == true)
  2475. {
  2476. XElement trPr = Xml.Element(XName.Get("trPr", DocX.w.NamespaceName));
  2477. if (trPr != null)
  2478. {
  2479. XElement trCantSplit = trPr.Element(XName.Get("cantSplit", DocX.w.NamespaceName));
  2480. if (trCantSplit != null)
  2481. trCantSplit.Remove();
  2482. }
  2483. }
  2484. }
  2485. }
  2486. /// <summary>
  2487. /// Merge cells starting with startIndex and ending with endIndex.
  2488. /// </summary>
  2489. public void MergeCells(int startIndex, int endIndex)
  2490. {
  2491. // Check for valid start and end indexes.
  2492. if (startIndex < 0 || endIndex <= startIndex || endIndex > Cells.Count + 1)
  2493. throw new IndexOutOfRangeException();
  2494. // The sum of all merged gridSpans.
  2495. int gridSpanSum = 0;
  2496. // Foreach each Cell between startIndex and endIndex inclusive.
  2497. foreach (Cell c in Cells.Where((z, i) => i > startIndex && i <= endIndex))
  2498. {
  2499. XElement tcPr = c.Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  2500. if (tcPr != null)
  2501. {
  2502. XElement gridSpan = tcPr.Element(XName.Get("gridSpan", DocX.w.NamespaceName));
  2503. if (gridSpan != null)
  2504. {
  2505. XAttribute val = gridSpan.Attribute(XName.Get("val", DocX.w.NamespaceName));
  2506. int value = 0;
  2507. if (val != null)
  2508. if (int.TryParse(val.Value, out value))
  2509. gridSpanSum += value - 1;
  2510. }
  2511. }
  2512. // Add this cells Pragraph to the merge start Cell.
  2513. Cells[startIndex].Xml.Add(c.Xml.Elements(XName.Get("p", DocX.w.NamespaceName)));
  2514. // Remove this Cell.
  2515. c.Xml.Remove();
  2516. }
  2517. /*
  2518. * Get the tcPr (table cell properties) element for the first cell in this merge,
  2519. * null will be returned if no such element exists.
  2520. */
  2521. XElement start_tcPr = Cells[startIndex].Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  2522. if (start_tcPr == null)
  2523. {
  2524. Cells[startIndex].Xml.SetElementValue(XName.Get("tcPr", DocX.w.NamespaceName), string.Empty);
  2525. start_tcPr = Cells[startIndex].Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  2526. }
  2527. /*
  2528. * Get the gridSpan element of this row,
  2529. * null will be returned if no such element exists.
  2530. */
  2531. XElement start_gridSpan = start_tcPr.Element(XName.Get("gridSpan", DocX.w.NamespaceName));
  2532. if (start_gridSpan == null)
  2533. {
  2534. start_tcPr.SetElementValue(XName.Get("gridSpan", DocX.w.NamespaceName), string.Empty);
  2535. start_gridSpan = start_tcPr.Element(XName.Get("gridSpan", DocX.w.NamespaceName));
  2536. }
  2537. /*
  2538. * Get the val attribute of this row,
  2539. * null will be returned if no such element exists.
  2540. */
  2541. XAttribute start_val = start_gridSpan.Attribute(XName.Get("val", DocX.w.NamespaceName));
  2542. int start_value = 0;
  2543. if (start_val != null)
  2544. if (int.TryParse(start_val.Value, out start_value))
  2545. gridSpanSum += start_value - 1;
  2546. // Set the val attribute to the number of merged cells.
  2547. start_gridSpan.SetAttributeValue(XName.Get("val", DocX.w.NamespaceName), (gridSpanSum + (endIndex - startIndex + 1)).ToString());
  2548. }
  2549. }
  2550. public class Cell : Container
  2551. {
  2552. internal Row row;
  2553. internal Cell(Row row, DocX document, XElement xml)
  2554. : base(document, xml)
  2555. {
  2556. this.row = row;
  2557. this.mainPart = row.mainPart;
  2558. }
  2559. public override ReadOnlyCollection<Paragraph> Paragraphs
  2560. {
  2561. get
  2562. {
  2563. ReadOnlyCollection<Paragraph> paragraphs = base.Paragraphs;
  2564. foreach (Paragraph p in paragraphs)
  2565. p.PackagePart = row.table.mainPart;
  2566. return paragraphs;
  2567. }
  2568. }
  2569. public int GridSpan
  2570. {
  2571. get
  2572. {
  2573. var somethin = int.Parse(this.Xml.Element(XName.Get("gridSpan", DocX.w.NamespaceName)).Attribute(XName.Get("Value", DocX.w.NamespaceName)).Value);
  2574. return somethin;
  2575. }
  2576. }
  2577. /// <summary>
  2578. /// Gets or Sets this Cells vertical alignment.
  2579. /// </summary>
  2580. /// <!--Patch 7398 added by lckuiper on Nov 16th 2010 @ 2:23 PM-->
  2581. /// <example>
  2582. /// Creates a table with 3 cells and sets the vertical alignment of each to 1 of the 3 available options.
  2583. /// <code>
  2584. /// // Create a new document.
  2585. ///using(DocX document = DocX.Create("Test.docx"))
  2586. ///{
  2587. /// // Insert a Table into this document.
  2588. /// Table t = document.InsertTable(3, 1);
  2589. ///
  2590. /// // Set the design of the Table such that we can easily identify cell boundaries.
  2591. /// t.Design = TableDesign.TableGrid;
  2592. ///
  2593. /// // Set the height of the row bigger than default.
  2594. /// // We need to be able to see the difference in vertical cell alignment options.
  2595. /// t.Rows[0].Height = 100;
  2596. ///
  2597. /// // Set the vertical alignment of cell0 to top.
  2598. /// Cell c0 = t.Rows[0].Cells[0];
  2599. /// c0.InsertParagraph("VerticalAlignment.Top");
  2600. /// c0.VerticalAlignment = VerticalAlignment.Top;
  2601. ///
  2602. /// // Set the vertical alignment of cell1 to center.
  2603. /// Cell c1 = t.Rows[0].Cells[1];
  2604. /// c1.InsertParagraph("VerticalAlignment.Center");
  2605. /// c1.VerticalAlignment = VerticalAlignment.Center;
  2606. ///
  2607. /// // Set the vertical alignment of cell2 to bottom.
  2608. /// Cell c2 = t.Rows[0].Cells[2];
  2609. /// c2.InsertParagraph("VerticalAlignment.Bottom");
  2610. /// c2.VerticalAlignment = VerticalAlignment.Bottom;
  2611. ///
  2612. /// // Save the document.
  2613. /// document.Save();
  2614. ///}
  2615. /// </code>
  2616. /// </example>
  2617. public VerticalAlignment VerticalAlignment
  2618. {
  2619. get
  2620. {
  2621. /*
  2622. * Get the tcPr (table cell properties) element for this Cell,
  2623. * null will be return if no such element exists.
  2624. */
  2625. XElement tcPr = Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  2626. // If tcPr is null, this cell contains no width information.
  2627. if (tcPr == null)
  2628. return VerticalAlignment.Center;
  2629. /*
  2630. * Get the vAlign (table cell vertical alignment) element for this Cell,
  2631. * null will be return if no such element exists.
  2632. */
  2633. XElement vAlign = tcPr.Element(XName.Get("vAlign", DocX.w.NamespaceName));
  2634. // If vAlign is null, this cell contains no vertical alignment information.
  2635. if (vAlign == null)
  2636. return VerticalAlignment.Center;
  2637. // Get the val attribute of the vAlign element.
  2638. XAttribute val = vAlign.Attribute(XName.Get("val", DocX.w.NamespaceName));
  2639. // If val is null, this cell contains no vAlign information.
  2640. if (val == null)
  2641. return VerticalAlignment.Center;
  2642. // If val is not a VerticalAlign enum, something is wrong with this attributes value, so remove it and return VerticalAlignment.Center;
  2643. try
  2644. {
  2645. return (VerticalAlignment)Enum.Parse(typeof(VerticalAlignment), val.Value, true);
  2646. }
  2647. catch
  2648. {
  2649. val.Remove();
  2650. return VerticalAlignment.Center;
  2651. }
  2652. }
  2653. set
  2654. {
  2655. /*
  2656. * Get the tcPr (table cell properties) element for this Cell,
  2657. * null will be return if no such element exists.
  2658. */
  2659. XElement tcPr = Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  2660. if (tcPr == null)
  2661. {
  2662. Xml.SetElementValue(XName.Get("tcPr", DocX.w.NamespaceName), string.Empty);
  2663. tcPr = Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  2664. }
  2665. /*
  2666. * Get the vAlign (table cell vertical alignment) element for this Cell,
  2667. * null will be return if no such element exists.
  2668. */
  2669. XElement vAlign = tcPr.Element(XName.Get("vAlign", DocX.w.NamespaceName));
  2670. if (vAlign == null)
  2671. {
  2672. tcPr.SetElementValue(XName.Get("vAlign", DocX.w.NamespaceName), string.Empty);
  2673. vAlign = tcPr.Element(XName.Get("vAlign", DocX.w.NamespaceName));
  2674. }
  2675. // Set the VerticalAlignment in 'val'
  2676. vAlign.SetAttributeValue(XName.Get("val", DocX.w.NamespaceName), value.ToString().ToLower());
  2677. }
  2678. }
  2679. public Color Shading
  2680. {
  2681. get
  2682. {
  2683. /*
  2684. * Get the tcPr (table cell properties) element for this Cell,
  2685. * null will be return if no such element exists.
  2686. */
  2687. XElement tcPr = Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  2688. // If tcPr is null, this cell contains no Color information.
  2689. if (tcPr == null)
  2690. return Color.White;
  2691. /*
  2692. * Get the shd (table shade) element for this Cell,
  2693. * null will be return if no such element exists.
  2694. */
  2695. XElement shd = tcPr.Element(XName.Get("shd", DocX.w.NamespaceName));
  2696. // If shd is null, this cell contains no Color information.
  2697. if (shd == null)
  2698. return Color.White;
  2699. // Get the w attribute of the tcW element.
  2700. XAttribute fill = shd.Attribute(XName.Get("fill", DocX.w.NamespaceName));
  2701. // If fill is null, this cell contains no Color information.
  2702. if (fill == null)
  2703. return Color.White;
  2704. return ColorTranslator.FromHtml(string.Format("#{0}", fill.Value));
  2705. }
  2706. set
  2707. {
  2708. /*
  2709. * Get the tcPr (table cell properties) element for this Cell,
  2710. * null will be return if no such element exists.
  2711. */
  2712. XElement tcPr = Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  2713. if (tcPr == null)
  2714. {
  2715. Xml.SetElementValue(XName.Get("tcPr", DocX.w.NamespaceName), string.Empty);
  2716. tcPr = Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  2717. }
  2718. /*
  2719. * Get the shd (table shade) element for this Cell,
  2720. * null will be return if no such element exists.
  2721. */
  2722. XElement shd = tcPr.Element(XName.Get("shd", DocX.w.NamespaceName));
  2723. if (shd == null)
  2724. {
  2725. tcPr.SetElementValue(XName.Get("shd", DocX.w.NamespaceName), string.Empty);
  2726. shd = tcPr.Element(XName.Get("shd", DocX.w.NamespaceName));
  2727. }
  2728. // The val attribute needs to be set to clear
  2729. shd.SetAttributeValue(XName.Get("val", DocX.w.NamespaceName), "clear");
  2730. // The color attribute needs to be set to auto
  2731. shd.SetAttributeValue(XName.Get("color", DocX.w.NamespaceName), "auto");
  2732. // The fill attribute needs to be set to the hex for this Color.
  2733. shd.SetAttributeValue(XName.Get("fill", DocX.w.NamespaceName), value.ToHex());
  2734. }
  2735. }
  2736. /// <summary>
  2737. /// Width in pixels. // Added by Joel, refactored by Cathal
  2738. /// </summary>
  2739. public double Width
  2740. {
  2741. get
  2742. {
  2743. /*
  2744. * Get the tcPr (table cell properties) element for this Cell,
  2745. * null will be return if no such element exists.
  2746. */
  2747. XElement tcPr = Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  2748. // If tcPr is null, this cell contains no width information.
  2749. if (tcPr == null)
  2750. return double.NaN;
  2751. /*
  2752. * Get the tcW (table cell width) element for this Cell,
  2753. * null will be return if no such element exists.
  2754. */
  2755. XElement tcW = tcPr.Element(XName.Get("tcW", DocX.w.NamespaceName));
  2756. // If tcW is null, this cell contains no width information.
  2757. if (tcW == null)
  2758. return double.NaN;
  2759. // Get the w attribute of the tcW element.
  2760. XAttribute w = tcW.Attribute(XName.Get("w", DocX.w.NamespaceName));
  2761. // If w is null, this cell contains no width information.
  2762. if (w == null)
  2763. return double.NaN;
  2764. // If w is not a double, something is wrong with this attributes value, so remove it and return double.NaN;
  2765. double widthInWordUnits;
  2766. if (!double.TryParse(w.Value, out widthInWordUnits))
  2767. {
  2768. w.Remove();
  2769. return double.NaN;
  2770. }
  2771. // 15 "word units" is equal to one pixel.
  2772. return (widthInWordUnits / 15);
  2773. }
  2774. set
  2775. {
  2776. /*
  2777. * Get the tcPr (table cell properties) element for this Cell,
  2778. * null will be return if no such element exists.
  2779. */
  2780. XElement tcPr = Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  2781. if (tcPr == null)
  2782. {
  2783. Xml.SetElementValue(XName.Get("tcPr", DocX.w.NamespaceName), string.Empty);
  2784. tcPr = Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  2785. }
  2786. /*
  2787. * Get the tcW (table cell width) element for this Cell,
  2788. * null will be return if no such element exists.
  2789. */
  2790. XElement tcW = tcPr.Element(XName.Get("tcW", DocX.w.NamespaceName));
  2791. if (tcW == null)
  2792. {
  2793. tcPr.SetElementValue(XName.Get("tcW", DocX.w.NamespaceName), string.Empty);
  2794. tcW = tcPr.Element(XName.Get("tcW", DocX.w.NamespaceName));
  2795. }
  2796. if (value == -1)
  2797. {
  2798. // remove cell width; due to set on table prop.
  2799. tcW.Remove();
  2800. return;
  2801. //tcW.SetAttributeValue(XName.Get("type", DocX.w.NamespaceName), "auto");
  2802. //return;
  2803. }
  2804. // The type attribute needs to be set to dxa which represents "twips" or twentieths of a point. In other words, 1/1440th of an inch.
  2805. tcW.SetAttributeValue(XName.Get("type", DocX.w.NamespaceName), "dxa");
  2806. // 15 "word units" is equal to one pixel.
  2807. tcW.SetAttributeValue(XName.Get("w", DocX.w.NamespaceName), (value * 15).ToString());
  2808. }
  2809. }
  2810. /// <summary>
  2811. /// LeftMargin in pixels. // Added by lckuiper
  2812. /// </summary>
  2813. /// <example>
  2814. /// <code>
  2815. /// // Create a new document.
  2816. ///using (DocX document = DocX.Create("Test.docx"))
  2817. ///{
  2818. /// // Insert table into this document.
  2819. /// Table t = document.InsertTable(3, 3);
  2820. /// t.Design = TableDesign.TableGrid;
  2821. ///
  2822. /// // Get the center cell.
  2823. /// Cell center = t.Rows[1].Cells[1];
  2824. ///
  2825. /// // Insert some text so that we can see the effect of the Margins.
  2826. /// center.Paragraphs[0].Append("Center Cell");
  2827. ///
  2828. /// // Set the center cells Left, Margin to 10.
  2829. /// center.MarginLeft = 25;
  2830. ///
  2831. /// // Save the document.
  2832. /// document.Save();
  2833. ///}
  2834. /// </code>
  2835. /// </example>
  2836. public double MarginLeft
  2837. {
  2838. get
  2839. {
  2840. /*
  2841. * Get the tcPr (table cell properties) element for this Cell,
  2842. * null will be return if no such element exists.
  2843. */
  2844. XElement tcPr = Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  2845. // If tcPr is null, this cell contains no width information.
  2846. if (tcPr == null)
  2847. return double.NaN;
  2848. /*
  2849. * Get the tcMar
  2850. *
  2851. */
  2852. XElement tcMar = tcPr.Element(XName.Get("tcMar", DocX.w.NamespaceName));
  2853. // If tcMar is null, this cell contains no margin information.
  2854. if (tcMar == null)
  2855. return double.NaN;
  2856. // Get the left (LeftMargin) element
  2857. XElement tcMarLeft = tcMar.Element(XName.Get("left", DocX.w.NamespaceName));
  2858. // If tcMarLeft is null, this cell contains no left margin information.
  2859. if (tcMarLeft == null)
  2860. return double.NaN;
  2861. // Get the w attribute of the tcMarLeft element.
  2862. XAttribute w = tcMarLeft.Attribute(XName.Get("w", DocX.w.NamespaceName));
  2863. // If w is null, this cell contains no width information.
  2864. if (w == null)
  2865. return double.NaN;
  2866. // If w is not a double, something is wrong with this attributes value, so remove it and return double.NaN;
  2867. double leftMarginInWordUnits;
  2868. if (!double.TryParse(w.Value, out leftMarginInWordUnits))
  2869. {
  2870. w.Remove();
  2871. return double.NaN;
  2872. }
  2873. // 15 "word units" is equal to one pixel.
  2874. return (leftMarginInWordUnits / 15);
  2875. }
  2876. set
  2877. {
  2878. /*
  2879. * Get the tcPr (table cell properties) element for this Cell,
  2880. * null will be return if no such element exists.
  2881. */
  2882. XElement tcPr = Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  2883. if (tcPr == null)
  2884. {
  2885. Xml.SetElementValue(XName.Get("tcPr", DocX.w.NamespaceName), string.Empty);
  2886. tcPr = Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  2887. }
  2888. /*
  2889. * Get the tcMar (table cell margin) element for this Cell,
  2890. * null will be return if no such element exists.
  2891. */
  2892. XElement tcMar = tcPr.Element(XName.Get("tcMar", DocX.w.NamespaceName));
  2893. if (tcMar == null)
  2894. {
  2895. tcPr.SetElementValue(XName.Get("tcMar", DocX.w.NamespaceName), string.Empty);
  2896. tcMar = tcPr.Element(XName.Get("tcMar", DocX.w.NamespaceName));
  2897. }
  2898. /*
  2899. * Get the left (table cell left margin) element for this Cell,
  2900. * null will be return if no such element exists.
  2901. */
  2902. XElement tcMarLeft = tcMar.Element(XName.Get("left", DocX.w.NamespaceName));
  2903. if (tcMarLeft == null)
  2904. {
  2905. tcMar.SetElementValue(XName.Get("left", DocX.w.NamespaceName), string.Empty);
  2906. tcMarLeft = tcMar.Element(XName.Get("left", DocX.w.NamespaceName));
  2907. }
  2908. // The type attribute needs to be set to dxa which represents "twips" or twentieths of a point. In other words, 1/1440th of an inch.
  2909. tcMarLeft.SetAttributeValue(XName.Get("type", DocX.w.NamespaceName), "dxa");
  2910. // 15 "word units" is equal to one pixel.
  2911. tcMarLeft.SetAttributeValue(XName.Get("w", DocX.w.NamespaceName), (value * 15).ToString());
  2912. }
  2913. }
  2914. /// <summary>
  2915. /// RightMargin in pixels. // Added by lckuiper
  2916. /// </summary>
  2917. /// <example>
  2918. /// <code>
  2919. /// // Create a new document.
  2920. ///using (DocX document = DocX.Create("Test.docx"))
  2921. ///{
  2922. /// // Insert table into this document.
  2923. /// Table t = document.InsertTable(3, 3);
  2924. /// t.Design = TableDesign.TableGrid;
  2925. ///
  2926. /// // Get the center cell.
  2927. /// Cell center = t.Rows[1].Cells[1];
  2928. ///
  2929. /// // Insert some text so that we can see the effect of the Margins.
  2930. /// center.Paragraphs[0].Append("Center Cell");
  2931. ///
  2932. /// // Set the center cells Right, Margin to 10.
  2933. /// center.MarginRight = 25;
  2934. ///
  2935. /// // Save the document.
  2936. /// document.Save();
  2937. ///}
  2938. /// </code>
  2939. /// </example>
  2940. public double MarginRight
  2941. {
  2942. get
  2943. {
  2944. /*
  2945. * Get the tcPr (table cell properties) element for this Cell,
  2946. * null will be return if no such element exists.
  2947. */
  2948. XElement tcPr = Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  2949. // If tcPr is null, this cell contains no width information.
  2950. if (tcPr == null)
  2951. return double.NaN;
  2952. /*
  2953. * Get the tcMar
  2954. *
  2955. */
  2956. XElement tcMar = tcPr.Element(XName.Get("tcMar", DocX.w.NamespaceName));
  2957. // If tcMar is null, this cell contains no margin information.
  2958. if (tcMar == null)
  2959. return double.NaN;
  2960. // Get the right (RightMargin) element
  2961. XElement tcMarRight = tcMar.Element(XName.Get("right", DocX.w.NamespaceName));
  2962. // If tcMarRight is null, this cell contains no right margin information.
  2963. if (tcMarRight == null)
  2964. return double.NaN;
  2965. // Get the w attribute of the tcMarRight element.
  2966. XAttribute w = tcMarRight.Attribute(XName.Get("w", DocX.w.NamespaceName));
  2967. // If w is null, this cell contains no width information.
  2968. if (w == null)
  2969. return double.NaN;
  2970. // If w is not a double, something is wrong with this attributes value, so remove it and return double.NaN;
  2971. double rightMarginInWordUnits;
  2972. if (!double.TryParse(w.Value, out rightMarginInWordUnits))
  2973. {
  2974. w.Remove();
  2975. return double.NaN;
  2976. }
  2977. // 15 "word units" is equal to one pixel.
  2978. return (rightMarginInWordUnits / 15);
  2979. }
  2980. set
  2981. {
  2982. /*
  2983. * Get the tcPr (table cell properties) element for this Cell,
  2984. * null will be return if no such element exists.
  2985. */
  2986. XElement tcPr = Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  2987. if (tcPr == null)
  2988. {
  2989. Xml.SetElementValue(XName.Get("tcPr", DocX.w.NamespaceName), string.Empty);
  2990. tcPr = Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  2991. }
  2992. /*
  2993. * Get the tcMar (table cell margin) element for this Cell,
  2994. * null will be return if no such element exists.
  2995. */
  2996. XElement tcMar = tcPr.Element(XName.Get("tcMar", DocX.w.NamespaceName));
  2997. if (tcMar == null)
  2998. {
  2999. tcPr.SetElementValue(XName.Get("tcMar", DocX.w.NamespaceName), string.Empty);
  3000. tcMar = tcPr.Element(XName.Get("tcMar", DocX.w.NamespaceName));
  3001. }
  3002. /*
  3003. * Get the right (table cell right margin) element for this Cell,
  3004. * null will be return if no such element exists.
  3005. */
  3006. XElement tcMarRight = tcMar.Element(XName.Get("right", DocX.w.NamespaceName));
  3007. if (tcMarRight == null)
  3008. {
  3009. tcMar.SetElementValue(XName.Get("right", DocX.w.NamespaceName), string.Empty);
  3010. tcMarRight = tcMar.Element(XName.Get("right", DocX.w.NamespaceName));
  3011. }
  3012. // The type attribute needs to be set to dxa which represents "twips" or twentieths of a point. In other words, 1/1440th of an inch.
  3013. tcMarRight.SetAttributeValue(XName.Get("type", DocX.w.NamespaceName), "dxa");
  3014. // 15 "word units" is equal to one pixel.
  3015. tcMarRight.SetAttributeValue(XName.Get("w", DocX.w.NamespaceName), (value * 15).ToString());
  3016. }
  3017. }
  3018. /// <summary>
  3019. /// TopMargin in pixels. // Added by lckuiper
  3020. /// </summary>
  3021. /// <example>
  3022. /// <code>
  3023. /// // Create a new document.
  3024. ///using (DocX document = DocX.Create("Test.docx"))
  3025. ///{
  3026. /// // Insert table into this document.
  3027. /// Table t = document.InsertTable(3, 3);
  3028. /// t.Design = TableDesign.TableGrid;
  3029. ///
  3030. /// // Get the center cell.
  3031. /// Cell center = t.Rows[1].Cells[1];
  3032. ///
  3033. /// // Insert some text so that we can see the effect of the Margins.
  3034. /// center.Paragraphs[0].Append("Center Cell");
  3035. ///
  3036. /// // Set the center cells Top, Margin to 10.
  3037. /// center.MarginTop = 25;
  3038. ///
  3039. /// // Save the document.
  3040. /// document.Save();
  3041. ///}
  3042. /// </code>
  3043. /// </example>
  3044. public double MarginTop
  3045. {
  3046. get
  3047. {
  3048. /*
  3049. * Get the tcPr (table cell properties) element for this Cell,
  3050. * null will be return if no such element exists.
  3051. */
  3052. XElement tcPr = Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  3053. // If tcPr is null, this cell contains no width information.
  3054. if (tcPr == null)
  3055. return double.NaN;
  3056. /*
  3057. * Get the tcMar
  3058. *
  3059. */
  3060. XElement tcMar = tcPr.Element(XName.Get("tcMar", DocX.w.NamespaceName));
  3061. // If tcMar is null, this cell contains no margin information.
  3062. if (tcMar == null)
  3063. return double.NaN;
  3064. // Get the top (TopMargin) element
  3065. XElement tcMarTop = tcMar.Element(XName.Get("top", DocX.w.NamespaceName));
  3066. // If tcMarTop is null, this cell contains no top margin information.
  3067. if (tcMarTop == null)
  3068. return double.NaN;
  3069. // Get the w attribute of the tcMarTop element.
  3070. XAttribute w = tcMarTop.Attribute(XName.Get("w", DocX.w.NamespaceName));
  3071. // If w is null, this cell contains no width information.
  3072. if (w == null)
  3073. return double.NaN;
  3074. // If w is not a double, something is wrong with this attributes value, so remove it and return double.NaN;
  3075. double topMarginInWordUnits;
  3076. if (!double.TryParse(w.Value, out topMarginInWordUnits))
  3077. {
  3078. w.Remove();
  3079. return double.NaN;
  3080. }
  3081. // 15 "word units" is equal to one pixel.
  3082. return (topMarginInWordUnits / 15);
  3083. }
  3084. set
  3085. {
  3086. /*
  3087. * Get the tcPr (table cell properties) element for this Cell,
  3088. * null will be return if no such element exists.
  3089. */
  3090. XElement tcPr = Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  3091. if (tcPr == null)
  3092. {
  3093. Xml.SetElementValue(XName.Get("tcPr", DocX.w.NamespaceName), string.Empty);
  3094. tcPr = Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  3095. }
  3096. /*
  3097. * Get the tcMar (table cell margin) element for this Cell,
  3098. * null will be return if no such element exists.
  3099. */
  3100. XElement tcMar = tcPr.Element(XName.Get("tcMar", DocX.w.NamespaceName));
  3101. if (tcMar == null)
  3102. {
  3103. tcPr.SetElementValue(XName.Get("tcMar", DocX.w.NamespaceName), string.Empty);
  3104. tcMar = tcPr.Element(XName.Get("tcMar", DocX.w.NamespaceName));
  3105. }
  3106. /*
  3107. * Get the top (table cell top margin) element for this Cell,
  3108. * null will be return if no such element exists.
  3109. */
  3110. XElement tcMarTop = tcMar.Element(XName.Get("top", DocX.w.NamespaceName));
  3111. if (tcMarTop == null)
  3112. {
  3113. tcMar.SetElementValue(XName.Get("top", DocX.w.NamespaceName), string.Empty);
  3114. tcMarTop = tcMar.Element(XName.Get("top", DocX.w.NamespaceName));
  3115. }
  3116. // The type attribute needs to be set to dxa which represents "twips" or twentieths of a point. In other words, 1/1440th of an inch.
  3117. tcMarTop.SetAttributeValue(XName.Get("type", DocX.w.NamespaceName), "dxa");
  3118. // 15 "word units" is equal to one pixel.
  3119. tcMarTop.SetAttributeValue(XName.Get("w", DocX.w.NamespaceName), (value * 15).ToString());
  3120. }
  3121. }
  3122. /// <summary>
  3123. /// BottomMargin in pixels. // Added by lckuiper
  3124. /// </summary>
  3125. /// <example>
  3126. /// <code>
  3127. /// // Create a new document.
  3128. ///using (DocX document = DocX.Create("Test.docx"))
  3129. ///{
  3130. /// // Insert table into this document.
  3131. /// Table t = document.InsertTable(3, 3);
  3132. /// t.Design = TableDesign.TableGrid;
  3133. ///
  3134. /// // Get the center cell.
  3135. /// Cell center = t.Rows[1].Cells[1];
  3136. ///
  3137. /// // Insert some text so that we can see the effect of the Margins.
  3138. /// center.Paragraphs[0].Append("Center Cell");
  3139. ///
  3140. /// // Set the center cells Top, Margin to 10.
  3141. /// center.MarginBottom = 25;
  3142. ///
  3143. /// // Save the document.
  3144. /// document.Save();
  3145. ///}
  3146. /// </code>
  3147. /// </example>
  3148. public double MarginBottom
  3149. {
  3150. get
  3151. {
  3152. /*
  3153. * Get the tcPr (table cell properties) element for this Cell,
  3154. * null will be return if no such element exists.
  3155. */
  3156. XElement tcPr = Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  3157. // If tcPr is null, this cell contains no width information.
  3158. if (tcPr == null)
  3159. return double.NaN;
  3160. /*
  3161. * Get the tcMar
  3162. *
  3163. */
  3164. XElement tcMar = tcPr.Element(XName.Get("tcMar", DocX.w.NamespaceName));
  3165. // If tcMar is null, this cell contains no margin information.
  3166. if (tcMar == null)
  3167. return double.NaN;
  3168. // Get the bottom (BottomMargin) element
  3169. XElement tcMarBottom = tcMar.Element(XName.Get("bottom", DocX.w.NamespaceName));
  3170. // If tcMarBottom is null, this cell contains no bottom margin information.
  3171. if (tcMarBottom == null)
  3172. return double.NaN;
  3173. // Get the w attribute of the tcMarBottom element.
  3174. XAttribute w = tcMarBottom.Attribute(XName.Get("w", DocX.w.NamespaceName));
  3175. // If w is null, this cell contains no width information.
  3176. if (w == null)
  3177. return double.NaN;
  3178. // If w is not a double, something is wrong with this attributes value, so remove it and return double.NaN;
  3179. double bottomMarginInWordUnits;
  3180. if (!double.TryParse(w.Value, out bottomMarginInWordUnits))
  3181. {
  3182. w.Remove();
  3183. return double.NaN;
  3184. }
  3185. // 15 "word units" is equal to one pixel.
  3186. return (bottomMarginInWordUnits / 15);
  3187. }
  3188. set
  3189. {
  3190. /*
  3191. * Get the tcPr (table cell properties) element for this Cell,
  3192. * null will be return if no such element exists.
  3193. */
  3194. XElement tcPr = Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  3195. if (tcPr == null)
  3196. {
  3197. Xml.SetElementValue(XName.Get("tcPr", DocX.w.NamespaceName), string.Empty);
  3198. tcPr = Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  3199. }
  3200. /*
  3201. * Get the tcMar (table cell margin) element for this Cell,
  3202. * null will be return if no such element exists.
  3203. */
  3204. XElement tcMar = tcPr.Element(XName.Get("tcMar", DocX.w.NamespaceName));
  3205. if (tcMar == null)
  3206. {
  3207. tcPr.SetElementValue(XName.Get("tcMar", DocX.w.NamespaceName), string.Empty);
  3208. tcMar = tcPr.Element(XName.Get("tcMar", DocX.w.NamespaceName));
  3209. }
  3210. /*
  3211. * Get the bottom (table cell bottom margin) element for this Cell,
  3212. * null will be return if no such element exists.
  3213. */
  3214. XElement tcMarBottom = tcMar.Element(XName.Get("bottom", DocX.w.NamespaceName));
  3215. if (tcMarBottom == null)
  3216. {
  3217. tcMar.SetElementValue(XName.Get("bottom", DocX.w.NamespaceName), string.Empty);
  3218. tcMarBottom = tcMar.Element(XName.Get("bottom", DocX.w.NamespaceName));
  3219. }
  3220. // The type attribute needs to be set to dxa which represents "twips" or twentieths of a point. In other words, 1/1440th of an inch.
  3221. tcMarBottom.SetAttributeValue(XName.Get("type", DocX.w.NamespaceName), "dxa");
  3222. // 15 "word units" is equal to one pixel.
  3223. tcMarBottom.SetAttributeValue(XName.Get("w", DocX.w.NamespaceName), (value * 15).ToString());
  3224. }
  3225. }
  3226. /// <summary>
  3227. /// Set the table cell border
  3228. /// Added by lckuiper @ 20101117
  3229. /// </summary>
  3230. /// <example>
  3231. /// <code>
  3232. /// // Create a new document.
  3233. ///using (DocX document = DocX.Create("Test.docx"))
  3234. ///{
  3235. /// // Insert a table into this document.
  3236. /// Table t = document.InsertTable(3, 3);
  3237. ///
  3238. /// // Get the center cell.
  3239. /// Cell center = t.Rows[1].Cells[1];
  3240. ///
  3241. /// // Create a large blue border.
  3242. /// Border b = new Border(BorderStyle.Tcbs_single, BorderSize.seven, 0, Color.Blue);
  3243. ///
  3244. /// // Set the center cells Top, Bottom, Left and Right Borders to b.
  3245. /// center.SetBorder(TableCellBorderType.Top, b);
  3246. /// center.SetBorder(TableCellBorderType.Bottom, b);
  3247. /// center.SetBorder(TableCellBorderType.Left, b);
  3248. /// center.SetBorder(TableCellBorderType.Right, b);
  3249. ///
  3250. /// // Save the document.
  3251. /// document.Save();
  3252. ///}
  3253. /// </code>
  3254. /// </example>
  3255. /// <param name="borderType">Table Cell border to set</param>
  3256. /// <param name="border">Border object to set the table cell border</param>
  3257. public void SetBorder(TableCellBorderType borderType, Border border)
  3258. {
  3259. /*
  3260. * Get the tcPr (table cell properties) element for this Cell,
  3261. * null will be return if no such element exists.
  3262. */
  3263. XElement tcPr = Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  3264. if (tcPr == null)
  3265. {
  3266. Xml.SetElementValue(XName.Get("tcPr", DocX.w.NamespaceName), string.Empty);
  3267. tcPr = Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  3268. }
  3269. /*
  3270. * Get the tblBorders (table cell borders) element for this Cell,
  3271. * null will be return if no such element exists.
  3272. */
  3273. XElement tcBorders = tcPr.Element(XName.Get("tcBorders", DocX.w.NamespaceName));
  3274. if (tcBorders == null)
  3275. {
  3276. tcPr.SetElementValue(XName.Get("tcBorders", DocX.w.NamespaceName), string.Empty);
  3277. tcBorders = tcPr.Element(XName.Get("tcBorders", DocX.w.NamespaceName));
  3278. }
  3279. /*
  3280. * Get the 'borderType' (table cell border) element for this Cell,
  3281. * null will be return if no such element exists.
  3282. */
  3283. string tcbordertype;
  3284. switch (borderType)
  3285. {
  3286. case TableCellBorderType.TopLeftToBottomRight:
  3287. tcbordertype = "tl2br";
  3288. break;
  3289. case TableCellBorderType.TopRightToBottomLeft:
  3290. tcbordertype = "tr2bl";
  3291. break;
  3292. default:
  3293. // enum to string
  3294. tcbordertype = borderType.ToString();
  3295. // only lower the first char of string (because of insideH and insideV)
  3296. tcbordertype = tcbordertype.Substring(0, 1).ToLower() + tcbordertype.Substring(1);
  3297. break;
  3298. }
  3299. XElement tcBorderType = tcBorders.Element(XName.Get(borderType.ToString(), DocX.w.NamespaceName));
  3300. if (tcBorderType == null)
  3301. {
  3302. tcBorders.SetElementValue(XName.Get(tcbordertype, DocX.w.NamespaceName), string.Empty);
  3303. tcBorderType = tcBorders.Element(XName.Get(tcbordertype, DocX.w.NamespaceName));
  3304. }
  3305. // get string value of border style
  3306. string borderstyle = border.Tcbs.ToString().Substring(5);
  3307. borderstyle = borderstyle.Substring(0, 1).ToLower() + borderstyle.Substring(1);
  3308. // The val attribute is used for the border style
  3309. tcBorderType.SetAttributeValue(XName.Get("val", DocX.w.NamespaceName), borderstyle);
  3310. int size;
  3311. switch (border.Size)
  3312. {
  3313. case BorderSize.one: size = 2; break;
  3314. case BorderSize.two: size = 4; break;
  3315. case BorderSize.three: size = 6; break;
  3316. case BorderSize.four: size = 8; break;
  3317. case BorderSize.five: size = 12; break;
  3318. case BorderSize.six: size = 18; break;
  3319. case BorderSize.seven: size = 24; break;
  3320. case BorderSize.eight: size = 36; break;
  3321. case BorderSize.nine: size = 48; break;
  3322. default: size = 2; break;
  3323. }
  3324. // The sz attribute is used for the border size
  3325. tcBorderType.SetAttributeValue(XName.Get("sz", DocX.w.NamespaceName), (size).ToString());
  3326. // The space attribute is used for the cell spacing (probably '0')
  3327. tcBorderType.SetAttributeValue(XName.Get("space", DocX.w.NamespaceName), (border.Space).ToString());
  3328. // The color attribute is used for the border color
  3329. tcBorderType.SetAttributeValue(XName.Get("color", DocX.w.NamespaceName), border.Color.ToHex());
  3330. }
  3331. /// <summary>
  3332. /// Get a table cell border
  3333. /// Added by lckuiper @ 20101117
  3334. /// </summary>
  3335. /// <param name="borderType">The table cell border to get</param>
  3336. public Border GetBorder(TableCellBorderType borderType)
  3337. {
  3338. // instance with default border values
  3339. Border b = new Border();
  3340. /*
  3341. * Get the tcPr (table cell properties) element for this Cell,
  3342. * null will be return if no such element exists.
  3343. */
  3344. XElement tcPr = Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  3345. if (tcPr == null)
  3346. {
  3347. // uses default border style
  3348. }
  3349. /*
  3350. * Get the tcBorders (table cell borders) element for this Cell,
  3351. * null will be return if no such element exists.
  3352. */
  3353. XElement tcBorders = tcPr.Element(XName.Get("tcBorders", DocX.w.NamespaceName));
  3354. if (tcBorders == null)
  3355. {
  3356. // uses default border style
  3357. }
  3358. /*
  3359. * Get the 'borderType' (cell border) element for this Cell,
  3360. * null will be return if no such element exists.
  3361. */
  3362. string tcbordertype;
  3363. tcbordertype = borderType.ToString();
  3364. switch (tcbordertype)
  3365. {
  3366. case "TopLeftToBottomRight":
  3367. tcbordertype = "tl2br";
  3368. break;
  3369. case "TopRightToBottomLeft":
  3370. tcbordertype = "tr2bl";
  3371. break;
  3372. default:
  3373. // only lower the first char of string (because of insideH and insideV)
  3374. tcbordertype = tcbordertype.Substring(0, 1).ToLower() + tcbordertype.Substring(1);
  3375. break;
  3376. }
  3377. XElement tcBorderType = tcBorders.Element(XName.Get(tcbordertype, DocX.w.NamespaceName));
  3378. if (tcBorderType == null)
  3379. {
  3380. // uses default border style
  3381. }
  3382. // The val attribute is used for the border style
  3383. XAttribute val = tcBorderType.Attribute(XName.Get("val", DocX.w.NamespaceName));
  3384. // If val is null, this cell contains no border information.
  3385. if (val == null)
  3386. {
  3387. // uses default border style
  3388. }
  3389. else
  3390. {
  3391. try
  3392. {
  3393. string bordertype = "Tcbs_" + val.Value;
  3394. b.Tcbs = (BorderStyle)Enum.Parse(typeof(BorderStyle), bordertype);
  3395. }
  3396. catch
  3397. {
  3398. val.Remove();
  3399. // uses default border style
  3400. }
  3401. }
  3402. // The sz attribute is used for the border size
  3403. XAttribute sz = tcBorderType.Attribute(XName.Get("sz", DocX.w.NamespaceName));
  3404. // If sz is null, this border contains no size information.
  3405. if (sz == null)
  3406. {
  3407. // uses default border style
  3408. }
  3409. else
  3410. {
  3411. // If sz is not an int, something is wrong with this attributes value, so remove it
  3412. int numerical_size;
  3413. if (!int.TryParse(sz.Value, out numerical_size))
  3414. sz.Remove();
  3415. else
  3416. {
  3417. switch (numerical_size)
  3418. {
  3419. case 2: b.Size = BorderSize.one; break;
  3420. case 4: b.Size = BorderSize.two; break;
  3421. case 6: b.Size = BorderSize.three; break;
  3422. case 8: b.Size = BorderSize.four; break;
  3423. case 12: b.Size = BorderSize.five; break;
  3424. case 18: b.Size = BorderSize.six; break;
  3425. case 24: b.Size = BorderSize.seven; break;
  3426. case 36: b.Size = BorderSize.eight; break;
  3427. case 48: b.Size = BorderSize.nine; break;
  3428. default: b.Size = BorderSize.one; break;
  3429. }
  3430. }
  3431. }
  3432. // The space attribute is used for the border spacing (probably '0')
  3433. XAttribute space = tcBorderType.Attribute(XName.Get("space", DocX.w.NamespaceName));
  3434. // If space is null, this border contains no space information.
  3435. if (space == null)
  3436. {
  3437. // uses default border style
  3438. }
  3439. else
  3440. {
  3441. // If space is not an int, something is wrong with this attributes value, so remove it
  3442. int borderspace;
  3443. if (!int.TryParse(space.Value, out borderspace))
  3444. {
  3445. space.Remove();
  3446. // uses default border style
  3447. }
  3448. else
  3449. {
  3450. b.Space = borderspace;
  3451. }
  3452. }
  3453. // The color attribute is used for the border color
  3454. XAttribute color = tcBorderType.Attribute(XName.Get("color", DocX.w.NamespaceName));
  3455. if (color == null)
  3456. {
  3457. // uses default border style
  3458. }
  3459. else
  3460. {
  3461. // If color is not a Color, something is wrong with this attributes value, so remove it
  3462. try
  3463. {
  3464. b.Color = ColorTranslator.FromHtml(string.Format("#{0}", color.Value));
  3465. }
  3466. catch
  3467. {
  3468. color.Remove();
  3469. // uses default border style
  3470. }
  3471. }
  3472. return b;
  3473. }
  3474. /// <summary>
  3475. /// Gets or Sets the fill color of this Cell.
  3476. /// </summary>
  3477. /// <example>
  3478. /// <code>
  3479. /// // Create a new document.
  3480. /// using (DocX document = DocX.Create("Test.docx"))
  3481. /// {
  3482. /// // Insert a table into this document.
  3483. /// Table t = document.InsertTable(3, 3);
  3484. ///
  3485. /// // Fill the first cell as Blue.
  3486. /// t.Rows[0].Cells[0].FillColor = Color.Blue;
  3487. /// // Fill the middle cell as Red.
  3488. /// t.Rows[1].Cells[1].FillColor = Color.Red;
  3489. /// // Fill the last cell as Green.
  3490. /// t.Rows[2].Cells[2].FillColor = Color.Green;
  3491. ///
  3492. /// // Save the document.
  3493. /// document.Save();
  3494. /// }
  3495. /// </code>
  3496. /// </example>
  3497. public Color FillColor
  3498. {
  3499. get
  3500. {
  3501. /*
  3502. * Get the tcPr (table cell properties) element for this Cell,
  3503. * null will be return if no such element exists.
  3504. */
  3505. XElement tcPr = Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  3506. if (tcPr == null)
  3507. return Color.Empty;
  3508. else
  3509. {
  3510. XElement shd = tcPr.Element(XName.Get("shd", DocX.w.NamespaceName));
  3511. if (shd == null)
  3512. return Color.Empty;
  3513. else
  3514. {
  3515. XAttribute fill = shd.Attribute(XName.Get("fill", DocX.w.NamespaceName));
  3516. if (fill == null)
  3517. return Color.Empty;
  3518. else
  3519. {
  3520. int argb = Int32.Parse(fill.Value.Replace("#", ""), NumberStyles.HexNumber);
  3521. return Color.FromArgb(argb);
  3522. }
  3523. }
  3524. }
  3525. }
  3526. set
  3527. {
  3528. /*
  3529. * Get the tcPr (table cell properties) element for this Cell,
  3530. * null will be return if no such element exists.
  3531. */
  3532. XElement tcPr = Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  3533. if (tcPr == null)
  3534. {
  3535. Xml.SetElementValue(XName.Get("tcPr", DocX.w.NamespaceName), string.Empty);
  3536. tcPr = Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  3537. }
  3538. /*
  3539. * Get the tcW (table cell width) element for this Cell,
  3540. * null will be return if no such element exists.
  3541. */
  3542. XElement shd = tcPr.Element(XName.Get("shd", DocX.w.NamespaceName));
  3543. if (shd == null)
  3544. {
  3545. tcPr.SetElementValue(XName.Get("shd", DocX.w.NamespaceName), string.Empty);
  3546. shd = tcPr.Element(XName.Get("shd", DocX.w.NamespaceName));
  3547. }
  3548. shd.SetAttributeValue(XName.Get("val", DocX.w.NamespaceName), "clear");
  3549. shd.SetAttributeValue(XName.Get("color", DocX.w.NamespaceName), "auto");
  3550. shd.SetAttributeValue(XName.Get("fill", DocX.w.NamespaceName), value.ToHex());
  3551. }
  3552. }
  3553. public override Table InsertTable(int rowCount, int columnCount)
  3554. {
  3555. Table table = base.InsertTable(rowCount, columnCount);
  3556. table.mainPart = mainPart;
  3557. InsertParagraph(); //Dmitchern, It is necessary to put paragraph in the end of the cell, without it MS-Word will say that the document is corrupted
  3558. //IMPORTANT: It will be better to check all methods that work with adding anything to cells
  3559. return table;
  3560. }
  3561. public TextDirection TextDirection
  3562. {
  3563. get
  3564. {
  3565. XElement tcPr = Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  3566. // If tcPr is null, this cell contains no width information.
  3567. if (tcPr == null)
  3568. return TextDirection.right;
  3569. XElement textDirection = tcPr.Element(XName.Get("textDirection", DocX.w.NamespaceName));
  3570. if (textDirection == null)
  3571. return TextDirection.right;
  3572. XAttribute val = textDirection.Attribute(XName.Get("val", DocX.w.NamespaceName));
  3573. if (val == null)
  3574. return TextDirection.right;
  3575. // If val is not a VerticalAlign enum, something is wrong with this attributes value, so remove it and return VerticalAlignment.Center;
  3576. try
  3577. {
  3578. return (TextDirection)Enum.Parse(typeof(TextDirection), val.Value, true);
  3579. }
  3580. catch
  3581. {
  3582. val.Remove();
  3583. return TextDirection.right;
  3584. }
  3585. }
  3586. set
  3587. {
  3588. /*
  3589. * Get the tcPr (table cell properties) element for this Cell,
  3590. * null will be return if no such element exists.
  3591. */
  3592. XElement tcPr = Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  3593. if (tcPr == null)
  3594. {
  3595. Xml.SetElementValue(XName.Get("tcPr", DocX.w.NamespaceName), string.Empty);
  3596. tcPr = Xml.Element(XName.Get("tcPr", DocX.w.NamespaceName));
  3597. }
  3598. /*
  3599. * Get the vAlign (table cell vertical alignment) element for this Cell,
  3600. * null will be return if no such element exists.
  3601. */
  3602. XElement textDirection = tcPr.Element(XName.Get("textDirection", DocX.w.NamespaceName));
  3603. if (textDirection == null)
  3604. {
  3605. tcPr.SetElementValue(XName.Get("textDirection", DocX.w.NamespaceName), string.Empty);
  3606. textDirection = tcPr.Element(XName.Get("textDirection", DocX.w.NamespaceName));
  3607. }
  3608. // Set the VerticalAlignment in 'val'
  3609. textDirection.SetAttributeValue(XName.Get("val", DocX.w.NamespaceName), value.ToString());
  3610. }
  3611. }
  3612. }
  3613. public class TableLook
  3614. {
  3615. public bool FirstRow { get; set; }
  3616. public bool LastRow { get; set; }
  3617. public bool FirstColumn { get; set; }
  3618. public bool LastColumn { get; set; }
  3619. public bool NoHorizontalBanding { get; set; }
  3620. public bool NoVerticalBanding { get; set; }
  3621. }
  3622. }