PageRenderTime 61ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 1ms

/thirdparties-extension/org.apache.poi.xwpf.converter.xhtml/src/main/java/org/apache/poi/xwpf/converter/xhtml/internal/XHTMLMapper.java

https://github.com/minstrelsy/xdocreport
Java | 602 lines | 462 code | 70 blank | 70 comment | 45 complexity | c14d668d23631990bd259d145ca65a83 MD5 | raw file
  1. /**
  2. * Copyright (C) 2011-2012 The XDocReport Team <xdocreport@googlegroups.com>
  3. *
  4. * All rights reserved.
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining
  7. * a copy of this software and associated documentation files (the
  8. * "Software"), to deal in the Software without restriction, including
  9. * without limitation the rights to use, copy, modify, merge, publish,
  10. * distribute, sublicense, and/or sell copies of the Software, and to
  11. * permit persons to whom the Software is furnished to do so, subject to
  12. * the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be
  15. * included in all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  20. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  21. * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  22. * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  23. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24. */
  25. package org.apache.poi.xwpf.converter.xhtml.internal;
  26. import static org.apache.poi.xwpf.converter.core.utils.DxaUtil.emu2points;
  27. import static org.apache.poi.xwpf.converter.xhtml.internal.XHTMLConstants.A_ELEMENT;
  28. import static org.apache.poi.xwpf.converter.xhtml.internal.XHTMLConstants.BODY_ELEMENT;
  29. import static org.apache.poi.xwpf.converter.xhtml.internal.XHTMLConstants.BR_ELEMENT;
  30. import static org.apache.poi.xwpf.converter.xhtml.internal.XHTMLConstants.CLASS_ATTR;
  31. import static org.apache.poi.xwpf.converter.xhtml.internal.XHTMLConstants.COLSPAN_ATTR;
  32. import static org.apache.poi.xwpf.converter.xhtml.internal.XHTMLConstants.DIV_ELEMENT;
  33. import static org.apache.poi.xwpf.converter.xhtml.internal.XHTMLConstants.HEAD_ELEMENT;
  34. import static org.apache.poi.xwpf.converter.xhtml.internal.XHTMLConstants.HREF_ATTR;
  35. import static org.apache.poi.xwpf.converter.xhtml.internal.XHTMLConstants.HTML_ELEMENT;
  36. import static org.apache.poi.xwpf.converter.xhtml.internal.XHTMLConstants.ID_ATTR;
  37. import static org.apache.poi.xwpf.converter.xhtml.internal.XHTMLConstants.IMG_ELEMENT;
  38. import static org.apache.poi.xwpf.converter.xhtml.internal.XHTMLConstants.P_ELEMENT;
  39. import static org.apache.poi.xwpf.converter.xhtml.internal.XHTMLConstants.ROWSPAN_ATTR;
  40. import static org.apache.poi.xwpf.converter.xhtml.internal.XHTMLConstants.SPAN_ELEMENT;
  41. import static org.apache.poi.xwpf.converter.xhtml.internal.XHTMLConstants.SRC_ATTR;
  42. import static org.apache.poi.xwpf.converter.xhtml.internal.XHTMLConstants.STYLE_ATTR;
  43. import static org.apache.poi.xwpf.converter.xhtml.internal.XHTMLConstants.TABLE_ELEMENT;
  44. import static org.apache.poi.xwpf.converter.xhtml.internal.XHTMLConstants.TD_ELEMENT;
  45. import static org.apache.poi.xwpf.converter.xhtml.internal.XHTMLConstants.TH_ELEMENT;
  46. import static org.apache.poi.xwpf.converter.xhtml.internal.XHTMLConstants.TR_ELEMENT;
  47. import static org.apache.poi.xwpf.converter.xhtml.internal.styles.CSSStylePropertyConstants.HEIGHT;
  48. import static org.apache.poi.xwpf.converter.xhtml.internal.styles.CSSStylePropertyConstants.MARGIN_BOTTOM;
  49. import static org.apache.poi.xwpf.converter.xhtml.internal.styles.CSSStylePropertyConstants.MARGIN_LEFT;
  50. import static org.apache.poi.xwpf.converter.xhtml.internal.styles.CSSStylePropertyConstants.MARGIN_RIGHT;
  51. import static org.apache.poi.xwpf.converter.xhtml.internal.styles.CSSStylePropertyConstants.MARGIN_TOP;
  52. import static org.apache.poi.xwpf.converter.xhtml.internal.styles.CSSStylePropertyConstants.WIDTH;
  53. import java.io.IOException;
  54. import java.math.BigInteger;
  55. import java.util.List;
  56. import org.apache.poi.xwpf.converter.core.IURIResolver;
  57. import org.apache.poi.xwpf.converter.core.IXWPFMasterPage;
  58. import org.apache.poi.xwpf.converter.core.ListItemContext;
  59. import org.apache.poi.xwpf.converter.core.XWPFDocumentVisitor;
  60. import org.apache.poi.xwpf.converter.core.styles.XWPFStylesDocument;
  61. import org.apache.poi.xwpf.converter.core.utils.DxaUtil;
  62. import org.apache.poi.xwpf.converter.core.utils.StringUtils;
  63. import org.apache.poi.xwpf.converter.xhtml.XHTMLOptions;
  64. import org.apache.poi.xwpf.converter.xhtml.internal.styles.CSSStyle;
  65. import org.apache.poi.xwpf.converter.xhtml.internal.styles.CSSStylesDocument;
  66. import org.apache.poi.xwpf.converter.xhtml.internal.utils.SAXHelper;
  67. import org.apache.poi.xwpf.converter.xhtml.internal.utils.StringEscapeUtils;
  68. import org.apache.poi.xwpf.usermodel.XWPFDocument;
  69. import org.apache.poi.xwpf.usermodel.XWPFFooter;
  70. import org.apache.poi.xwpf.usermodel.XWPFHeader;
  71. import org.apache.poi.xwpf.usermodel.XWPFParagraph;
  72. import org.apache.poi.xwpf.usermodel.XWPFPictureData;
  73. import org.apache.poi.xwpf.usermodel.XWPFRun;
  74. import org.apache.poi.xwpf.usermodel.XWPFTable;
  75. import org.apache.poi.xwpf.usermodel.XWPFTableCell;
  76. import org.apache.poi.xwpf.usermodel.XWPFTableRow;
  77. import org.apache.xmlbeans.XmlException;
  78. import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
  79. import org.openxmlformats.schemas.drawingml.x2006.picture.CTPicture;
  80. import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.STRelFromH.Enum;
  81. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBookmark;
  82. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBr;
  83. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtrRef;
  84. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr;
  85. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPTab;
  86. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPageMar;
  87. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPageSz;
  88. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr;
  89. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;
  90. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTabs;
  91. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblPr;
  92. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
  93. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText;
  94. import org.xml.sax.Attributes;
  95. import org.xml.sax.ContentHandler;
  96. import org.xml.sax.SAXException;
  97. import org.xml.sax.helpers.AttributesImpl;
  98. public class XHTMLMapper
  99. extends XWPFDocumentVisitor<Object, XHTMLOptions, XHTMLMasterPage>
  100. {
  101. private static final String WORD_MEDIA = "word/media/";
  102. private final ContentHandler contentHandler;
  103. private boolean generateStyles = true;
  104. private final IURIResolver resolver;
  105. private AttributesImpl currentRunAttributes;
  106. private boolean pageDiv;
  107. public XHTMLMapper( XWPFDocument document, ContentHandler contentHandler, XHTMLOptions options )
  108. throws Exception
  109. {
  110. super( document, options != null ? options : XHTMLOptions.getDefault() );
  111. this.contentHandler = contentHandler;
  112. this.resolver = getOptions().getURIResolver();
  113. this.pageDiv = false;
  114. }
  115. @Override
  116. protected XWPFStylesDocument createStylesDocument( XWPFDocument document )
  117. throws XmlException, IOException
  118. {
  119. return new CSSStylesDocument( document, options.isIgnoreStylesIfUnused(), options.getIndent() );
  120. }
  121. @Override
  122. protected Object startVisitDocument()
  123. throws Exception
  124. {
  125. if ( !options.isFragment() )
  126. {
  127. contentHandler.startDocument();
  128. // html start
  129. startElement( HTML_ELEMENT );
  130. // head start
  131. startElement( HEAD_ELEMENT );
  132. if ( generateStyles )
  133. {
  134. // styles
  135. ( (CSSStylesDocument) stylesDocument ).save( contentHandler );
  136. }
  137. // html end
  138. endElement( HEAD_ELEMENT );
  139. // body start
  140. startElement( BODY_ELEMENT );
  141. }
  142. return null;
  143. }
  144. @Override
  145. protected void endVisitDocument()
  146. throws Exception
  147. {
  148. if ( pageDiv )
  149. {
  150. endElement( DIV_ELEMENT );
  151. }
  152. if ( !options.isFragment() )
  153. {
  154. // body end
  155. endElement( BODY_ELEMENT );
  156. // html end
  157. endElement( HTML_ELEMENT );
  158. contentHandler.endDocument();
  159. }
  160. }
  161. @Override
  162. protected Object startVisitParagraph( XWPFParagraph paragraph, ListItemContext itemContext, Object parentContainer )
  163. throws Exception
  164. {
  165. // 1) create attributes
  166. // 1.1) Create "class" attributes.
  167. AttributesImpl attributes = createClassAttribute( paragraph.getStyleID() );
  168. // 1.2) Create "style" attributes.
  169. CTPPr pPr = paragraph.getCTP().getPPr();
  170. CSSStyle cssStyle = getStylesDocument().createCSSStyle( pPr );
  171. attributes = createStyleAttribute( cssStyle, attributes );
  172. // 2) create element
  173. startElement( P_ELEMENT, attributes );
  174. return null;
  175. }
  176. @Override
  177. protected void endVisitParagraph( XWPFParagraph paragraph, Object parentContainer, Object paragraphContainer )
  178. throws Exception
  179. {
  180. endElement( P_ELEMENT );
  181. }
  182. @Override
  183. protected void visitRun( XWPFRun run, boolean pageNumber, String url, Object paragraphContainer )
  184. throws Exception
  185. {
  186. XWPFParagraph paragraph = run.getParagraph();
  187. // 1) create attributes
  188. // 1.1) Create "class" attributes.
  189. this.currentRunAttributes = createClassAttribute( paragraph.getStyleID() );
  190. // 1.2) Create "style" attributes.
  191. CTRPr rPr = run.getCTR().getRPr();
  192. CSSStyle cssStyle = getStylesDocument().createCSSStyle( rPr );
  193. this.currentRunAttributes = createStyleAttribute( cssStyle, currentRunAttributes );
  194. if ( url != null )
  195. {
  196. // url is not null, generate a HTML a.
  197. AttributesImpl hyperlinkAttributes = new AttributesImpl();
  198. SAXHelper.addAttrValue( hyperlinkAttributes, HREF_ATTR, url );
  199. startElement( A_ELEMENT, hyperlinkAttributes );
  200. }
  201. super.visitRun( run, pageNumber, url, paragraphContainer );
  202. if ( url != null )
  203. {
  204. // url is not null, close the HTML a.
  205. // TODO : for the moment generate space to be ensure that a has some content.
  206. characters( " " );
  207. endElement( A_ELEMENT );
  208. }
  209. this.currentRunAttributes = null;
  210. }
  211. @Override
  212. protected void visitEmptyRun( Object paragraphContainer )
  213. throws Exception
  214. {
  215. startElement( BR_ELEMENT );
  216. endElement( BR_ELEMENT );
  217. }
  218. @Override
  219. protected void visitText( CTText ctText, boolean pageNumber, Object paragraphContainer )
  220. throws Exception
  221. {
  222. if ( currentRunAttributes != null )
  223. {
  224. startElement( SPAN_ELEMENT, currentRunAttributes );
  225. }
  226. String text = ctText.getStringValue();
  227. if ( StringUtils.isNotEmpty( text ) )
  228. {
  229. // Escape with HTML characters
  230. characters( StringEscapeUtils.escapeHtml( text ) );
  231. }
  232. // else
  233. // {
  234. // characters( SPACE_ENTITY );
  235. // }
  236. if ( currentRunAttributes != null )
  237. {
  238. endElement( SPAN_ELEMENT );
  239. }
  240. }
  241. @Override
  242. protected void visitTab( CTPTab o, Object paragraphContainer )
  243. throws Exception
  244. {
  245. }
  246. @Override
  247. protected void visitTabs( CTTabs tabs, Object paragraphContainer )
  248. throws Exception
  249. {
  250. }
  251. @Override
  252. protected void addNewLine( CTBr br, Object paragraphContainer )
  253. throws Exception
  254. {
  255. startElement( BR_ELEMENT );
  256. endElement( BR_ELEMENT );
  257. }
  258. @Override
  259. protected void pageBreak()
  260. throws Exception
  261. {
  262. }
  263. @Override
  264. protected void visitBookmark( CTBookmark bookmark, XWPFParagraph paragraph, Object paragraphContainer )
  265. throws Exception
  266. {
  267. AttributesImpl attributes = new AttributesImpl();
  268. SAXHelper.addAttrValue( attributes, ID_ATTR, bookmark.getName() );
  269. startElement( SPAN_ELEMENT, attributes );
  270. endElement( SPAN_ELEMENT );
  271. }
  272. @Override
  273. protected Object startVisitTable( XWPFTable table, float[] colWidths, Object tableContainer )
  274. throws Exception
  275. {
  276. // 1) create attributes
  277. // 1.1) Create class attributes.
  278. AttributesImpl attributes = createClassAttribute( table.getStyleID() );
  279. // 1.2) Create "style" attributes.
  280. CTTblPr tblPr = table.getCTTbl().getTblPr();
  281. CSSStyle cssStyle = getStylesDocument().createCSSStyle( tblPr );
  282. attributes = createStyleAttribute( cssStyle, attributes );
  283. // 2) create element
  284. startElement( TABLE_ELEMENT, attributes );
  285. return null;
  286. }
  287. @Override
  288. protected void endVisitTable( XWPFTable table, Object parentContainer, Object tableContainer )
  289. throws Exception
  290. {
  291. endElement( TABLE_ELEMENT );
  292. }
  293. @Override
  294. protected void startVisitTableRow( XWPFTableRow row, Object tableContainer, int rowIndex, boolean headerRow )
  295. throws Exception
  296. {
  297. // 1) create attributes
  298. // Create class attributes.
  299. XWPFTable table = row.getTable();
  300. AttributesImpl attributes = createClassAttribute( table.getStyleID() );
  301. // 2) create element
  302. if ( headerRow )
  303. {
  304. startElement( TH_ELEMENT, attributes );
  305. }
  306. else
  307. {
  308. startElement( TR_ELEMENT, attributes );
  309. }
  310. }
  311. @Override
  312. protected void endVisitTableRow( XWPFTableRow row, Object tableContainer, boolean firstRow, boolean lastRow,
  313. boolean headerRow )
  314. throws Exception
  315. {
  316. if ( headerRow )
  317. {
  318. endElement( TH_ELEMENT );
  319. }
  320. else
  321. {
  322. endElement( TR_ELEMENT );
  323. }
  324. }
  325. @Override
  326. protected Object startVisitTableCell( XWPFTableCell cell, Object tableContainer, boolean firstRow, boolean lastRow,
  327. boolean firstCell, boolean lastCell, List<XWPFTableCell> vMergeCells )
  328. throws Exception
  329. {
  330. // 1) create attributes
  331. // 1.1) Create class attributes.
  332. XWPFTableRow row = cell.getTableRow();
  333. XWPFTable table = row.getTable();
  334. AttributesImpl attributes = createClassAttribute( table.getStyleID() );
  335. // 1.2) Create "style" attributes.
  336. CTTcPr tcPr = cell.getCTTc().getTcPr();
  337. CSSStyle cssStyle = getStylesDocument().createCSSStyle( tcPr );
  338. attributes = createStyleAttribute( cssStyle, attributes );
  339. // colspan attribute
  340. BigInteger gridSpan = stylesDocument.getTableCellGridSpan( cell );
  341. if ( gridSpan != null )
  342. {
  343. attributes = SAXHelper.addAttrValue( attributes, COLSPAN_ATTR, gridSpan.intValue() );
  344. }
  345. if ( vMergeCells != null )
  346. {
  347. attributes = SAXHelper.addAttrValue( attributes, ROWSPAN_ATTR, vMergeCells.size() );
  348. }
  349. // 2) create element
  350. startElement( TD_ELEMENT, attributes );
  351. return null;
  352. }
  353. @Override
  354. protected void endVisitTableCell( XWPFTableCell cell, Object tableContainer, Object tableCellContainer )
  355. throws Exception
  356. {
  357. endElement( TD_ELEMENT );
  358. }
  359. @Override
  360. protected void visitHeader( XWPFHeader header, CTHdrFtrRef headerRef, CTSectPr sectPr, XHTMLMasterPage masterPage )
  361. throws Exception
  362. {
  363. // TODO Auto-generated method stub
  364. }
  365. @Override
  366. protected void visitFooter( XWPFFooter footer, CTHdrFtrRef footerRef, CTSectPr sectPr, XHTMLMasterPage masterPage )
  367. throws Exception
  368. {
  369. // TODO Auto-generated method stub
  370. }
  371. @Override
  372. protected void visitPicture( CTPicture picture,
  373. Float offsetX,
  374. Enum relativeFromH,
  375. Float offsetY,
  376. org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.STRelFromV.Enum relativeFromV,
  377. org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.STWrapText.Enum wrapText,
  378. Object parentContainer )
  379. throws Exception
  380. {
  381. AttributesImpl attributes = null;
  382. // Src attribute
  383. XWPFPictureData pictureData = super.getPictureData( picture );
  384. if ( pictureData != null )
  385. {
  386. // img/@src
  387. String src = pictureData.getFileName();
  388. if ( StringUtils.isNotEmpty( src ) )
  389. {
  390. src = resolver.resolve( WORD_MEDIA + src );
  391. attributes = SAXHelper.addAttrValue( attributes, SRC_ATTR, src );
  392. }
  393. CTPositiveSize2D ext = picture.getSpPr().getXfrm().getExt();
  394. // img/@width
  395. float width = emu2points( ext.getCx() );
  396. attributes = SAXHelper.addAttrValue( attributes, WIDTH, getStylesDocument().getValueAsPoint( width ) );
  397. // img/@height
  398. float height = emu2points( ext.getCy() );
  399. attributes = SAXHelper.addAttrValue( attributes, HEIGHT, getStylesDocument().getValueAsPoint( height ) );
  400. }
  401. if ( attributes != null )
  402. {
  403. startElement( IMG_ELEMENT, attributes );
  404. }
  405. }
  406. @Override
  407. protected void setActiveMasterPage( XHTMLMasterPage masterPage )
  408. {
  409. if ( pageDiv )
  410. {
  411. try
  412. {
  413. endElement( DIV_ELEMENT );
  414. }
  415. catch ( SAXException e )
  416. {
  417. e.printStackTrace();
  418. }
  419. }
  420. AttributesImpl attributes = new AttributesImpl();
  421. CSSStyle style = new CSSStyle( DIV_ELEMENT, null );
  422. CTSectPr sectPr = masterPage.getSectPr();
  423. CTPageSz pageSize = sectPr.getPgSz();
  424. if ( pageSize != null )
  425. {
  426. // Width
  427. BigInteger width = pageSize.getW();
  428. if ( width != null )
  429. {
  430. style.addProperty( WIDTH, getStylesDocument().getValueAsPoint( DxaUtil.dxa2points( width ) ) );
  431. }
  432. }
  433. CTPageMar pageMargin = sectPr.getPgMar();
  434. if ( pageMargin != null )
  435. {
  436. // margin bottom
  437. BigInteger marginBottom = pageMargin.getBottom();
  438. if ( marginBottom != null )
  439. {
  440. float marginBottomPt = DxaUtil.dxa2points( marginBottom );
  441. style.addProperty( MARGIN_BOTTOM, getStylesDocument().getValueAsPoint( marginBottomPt ) );
  442. }
  443. // margin top
  444. BigInteger marginTop = pageMargin.getTop();
  445. if ( marginTop != null )
  446. {
  447. float marginTopPt = DxaUtil.dxa2points( marginTop );
  448. style.addProperty( MARGIN_TOP, getStylesDocument().getValueAsPoint( marginTopPt ) );
  449. }
  450. // margin left
  451. BigInteger marginLeft = pageMargin.getLeft();
  452. if ( marginLeft != null )
  453. {
  454. float marginLeftPt = DxaUtil.dxa2points( marginLeft );
  455. style.addProperty( MARGIN_LEFT, getStylesDocument().getValueAsPoint( marginLeftPt ) );
  456. }
  457. // margin right
  458. BigInteger marginRight = pageMargin.getRight();
  459. if ( marginRight != null )
  460. {
  461. float marginRightPt = DxaUtil.dxa2points( marginRight );
  462. style.addProperty( MARGIN_RIGHT, getStylesDocument().getValueAsPoint( marginRightPt ) );
  463. }
  464. }
  465. String s = style.getInlineStyles();
  466. if ( StringUtils.isNotEmpty( s ) )
  467. {
  468. SAXHelper.addAttrValue( attributes, STYLE_ATTR, s );
  469. }
  470. try
  471. {
  472. startElement( DIV_ELEMENT, attributes );
  473. }
  474. catch ( SAXException e )
  475. {
  476. // TODO Auto-generated catch block
  477. e.printStackTrace();
  478. }
  479. pageDiv = true;
  480. }
  481. @Override
  482. protected IXWPFMasterPage createMasterPage( CTSectPr sectPr )
  483. {
  484. return new XHTMLMasterPage( sectPr );
  485. }
  486. private void startElement( String name )
  487. throws SAXException
  488. {
  489. startElement( name, null );
  490. }
  491. private void startElement( String name, Attributes attributes )
  492. throws SAXException
  493. {
  494. SAXHelper.startElement( contentHandler, name, attributes );
  495. }
  496. private void endElement( String name )
  497. throws SAXException
  498. {
  499. SAXHelper.endElement( contentHandler, name );
  500. }
  501. private void characters( String content )
  502. throws SAXException
  503. {
  504. SAXHelper.characters( contentHandler, content );
  505. }
  506. @Override
  507. public CSSStylesDocument getStylesDocument()
  508. {
  509. return (CSSStylesDocument) super.getStylesDocument();
  510. }
  511. private AttributesImpl createClassAttribute( String styleID )
  512. {
  513. String classNames = getStylesDocument().getClassNames( styleID );
  514. if ( StringUtils.isNotEmpty( classNames ) )
  515. {
  516. return SAXHelper.addAttrValue( null, CLASS_ATTR, classNames );
  517. }
  518. return null;
  519. }
  520. private AttributesImpl createStyleAttribute( CSSStyle cssStyle, AttributesImpl attributes )
  521. {
  522. if ( cssStyle != null )
  523. {
  524. String inlineStyles = cssStyle.getInlineStyles();
  525. if ( StringUtils.isNotEmpty( inlineStyles ) )
  526. {
  527. attributes = SAXHelper.addAttrValue( attributes, STYLE_ATTR, inlineStyles );
  528. }
  529. }
  530. return attributes;
  531. }
  532. }