Page 1 of 1

Export to html from docx

PostPosted: Tue May 20, 2014 1:28 am
by david.zhaowl
Hi everyone,

To continue my last post: http://www.docx4java.org/forums/xhtml-import-f28/insert-an-altchunk-within-a-table-cell-t1890.html?sid=8e1c49627334cb2731ae2f04a7792c98&sid=8e1c49627334cb2731ae2f04a7792c98#p6527.

After I import html into docx, I want to be able to export this part from docx to html. I wrapped the code in sample and have the code below:

Code: Select all
public class AltChunkAddOfTypeHtml {

   private static ObjectFactory factory;
   private final static String inputfilepath = System.getProperty("user.dir")
         + "/test.docx";

   public static void main(String[] args) throws Exception {

      WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage
            .createPackage();
      MainDocumentPart mdp = wordMLPackage.getMainDocumentPart();
      factory = Context.getWmlObjectFactory();
      Tbl table = factory.createTbl();
      Tr tableRow = factory.createTr();

      Tc tableCell = factory.createTc();

      wordMLPackage.getMainDocumentPart().addObject(table);

      String xhtml = "<html><head><title>Import me</title></head><body><p>Hello World!This is the html code converted into docx!!!</p><b>tested by david</b></body></html>";
      ;

      mdp.addAltChunk(AltChunkType.Xhtml, xhtml.getBytes(), tableCell);

      tableRow.getContent().add(tableCell);
      table.getContent().add(tableRow);
      // Round trip
      wordMLPackage = mdp.convertAltChunks();

      wordMLPackage.save(new java.io.File(inputfilepath));

      List<Object> tableCells = getAllElementFromObject(
            wordMLPackage.getMainDocumentPart(), Tc.class);
      System.out.println(tableCells.size());

      /* only one tc in wordMLPackage */
      List<Object> paragraphsInTc = getAllElementFromObject(
            tableCells.get(0), P.class);
      System.out.println(paragraphsInTc.size());
      System.out.println("Ready to create html.");

      WordprocessingMLPackage wordMLPackage2 = WordprocessingMLPackage
            .createPackage();
      for (Object o : paragraphsInTc) {

         wordMLPackage2.getMainDocumentPart().addObject(o);
      }

      HTMLSettings htmlSettings = Docx4J.createHTMLSettings();

      htmlSettings.setWmlPackage(wordMLPackage2);

      OutputStream os;
      os = new FileOutputStream(new java.io.File(
            System.getProperty("user.dir") + "/sample.html"));
      System.out.println("Creating html.");
      Docx4J.toHTML(htmlSettings, os, Docx4J.FLAG_EXPORT_PREFER_XSL);

   }

   private static List<Object> getAllElementFromObject(Object obj,
         Class<?> toSearch) {
      List<Object> result = new ArrayList<Object>();
      if (obj instanceof JAXBElement)
         obj = ((JAXBElement<?>) obj).getValue();

      if (obj.getClass().equals(toSearch))
         result.add(obj);
      else if (obj instanceof ContentAccessor) {
         List<?> children = ((ContentAccessor) obj).getContent();
         for (Object child : children) {
            result.addAll(getAllElementFromObject(child, toSearch));
         }

      }
      return result;
   }
}


It's working for me and below is the html I got:

Code: Select all
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><head><meta content="text/html; charset=utf-8" http-equiv="Content-Type" /><style><!--/*paged media */ div.header {display: none }div.footer {display: none } /*@media print { */@page { size: A4; margin: 10%; @top-center {content: element(header) } @bottom-center {content: element(footer) } }/*element styles*/ .del  {text-decoration:line-through;color:red;} .ins {text-decoration:none;background:#c0ffc0;padding:1px;}
/* TABLE STYLES */

/* PARAGRAPH STYLES */
.DocDefaults {display:block;margin-bottom: 4mm;line-height: 115%;font-size: 11.0pt;}
.Normal {display:block;}

/* CHARACTER STYLES */ span.DefaultParagraphFont {display:inline;}
--></style><script type="text/javascript"><!--function toggleDiv(divid){if(document.getElementById(divid).style.display == 'none'){document.getElementById(divid).style.display = 'block';}else{document.getElementById(divid).style.display = 'none';}}
--></script></head><body>
 
  <!-- userBodyTop goes here -->
 
  <div style="color:red">TO HIDE THESE MESSAGES, TURN OFF debug level logging for org.docx4j.convert.out.common.writer.AbstractMessageWriter </div>
 
  <div class="document">
 
  <p class="Normal DocDefaults " style="text-align: left;position: relative; margin-left: 0in;margin-bottom: 0in;"><span class="DefaultParagraphFont " style="font-weight: normal;color: #000000;font-style: normal;font-size: 11.0pt;;font-family: Calibri;">Hello World!This is the html code converted into docx!!!</span></p>
 
  <p class="Normal DocDefaults " style="text-align: left;position: relative; margin-left: 0in;margin-bottom: 0in;"><span class="DefaultParagraphFont " style="font-weight: bold;color: #000000;font-style: normal;font-size: 11.0pt;;font-family: Calibri;">tested by david</span></p></div>
   
  <!-- userBodyTail goes here -->
 
  </body></html>


As I need to save this html code into database, is there anyway to make the converted html clean? Just like before it was imported into docx? Like this:
Code: Select all
<html><head><title>Import me</title></head><body><p>Hello World!This is the html code converted into docx!!!</p><b>tested by david</b></body></html>


Or maybe is there a better solution to do the convert from docx to html?
Thanks in advance.

Re: Export to html from docx

PostPosted: Thu May 22, 2014 1:24 am
by david.zhaowl
Solved by reading paragraphs and runs from word, then add html tags. Put the code below:

Code: Select all
  /**
     * Convert the description in table cell back into html code to be saved into database
     *
     * @param tc
     * @return
     */
    private String convertTcToHtml(Tc tc) {
        StringBuilder sb = new StringBuilder();
        sb.append("<html><body>");

        List<Object> paragraphs = getAllElementFromObject(tc, P.class);
        if (paragraphs == null || paragraphs.size() == 0) {
            return null;
        }

        /* Description exported from alm only has one paragraph in word. */
        List<Object> runs = getAllElementFromObject(paragraphs.get(0), R.class);
        addRunsToHtmlStringBuffer(sb, runs);

        /* If user modify description in word it may generate more paragraphs in word. */
        if (paragraphs.size() > 1) {
            sb.append("
");
            for (int i = 1; i < paragraphs.size(); i++) {
                List<Object> moreRuns = getAllElementFromObject(paragraphs.get(i), R.class);
                addRunsToHtmlStringBuffer(sb, moreRuns);
                /* Every paragraph should be starting from a new line */
                sb.append("
");
            }
        }

        sb.append("</body></html>");
        return sb.toString();
    }

    /**
     * Add Texts of a list of Runs to the html string builder
     *
     * @param sb
     * @param runs
     */
    private void addRunsToHtmlStringBuffer(StringBuilder sb, List<Object> runs) {
        if (runs != null && runs.size() > 0) {
            for (Object r : runs) {
                R run = (R) r;

                List<Object> brs = getAllElementFromObject(run, Br.class);
                if (brs != null && brs.size() > 0) {
                    LOGGER.info("BR:");
                    sb.append("<br/>");
                }

                /* One run usually has one text */
                List<Object> texts = getAllElementFromObject(run, Text.class);
                if (texts != null && texts.size() > 0) {
                    StringBuilder text_sb = new StringBuilder();
                    for (Object t : texts) {
                        Text text = (Text) t;
                        text_sb.append(text.getValue());
                    }

                    String htmlText = replaceWithHtmlCharacters(text_sb.toString());

                    if (run.getRPr() != null && run.getRPr().getB() != null && (run.getRPr().getB().isVal())) {
                        LOGGER.info("Bold Text:");
                        sb.append("<b>");
                        sb.append(htmlText);
                        sb.append("</b>");
                    } else {
                        LOGGER.info("Normal Text:");
                        sb.append(htmlText);
                    }
                }
            }
        }
    }
 
    /**
     * Replace ", <, > with html special charactors
     *
     * @param text
     * @return
     */
    private String replaceWithHtmlCharacters(String text) {
        text = text.replace("\"", "&quot;");
        text = text.replace("<", "&lt;");
        text = text.replace(">", "&gt;");

        return text;
    }

Re: Export to html from docx

PostPosted: Tue May 27, 2014 1:18 pm
by jason
Hi David, Glad you got it doing what you wanted. A couple of years ago I customised the HTML export for a customer to produce minimalist output, but that code is not in docx4j per se. cheers .. Jason