Best way to 'export' to MS Word table

This forum can be used to talk about general design strategies, new ideas and questions in general related to wxWidgets. If you feel your questions doesn't fit anywhere, put it here.
Post Reply
iwbnwif
Super wx Problem Solver
Super wx Problem Solver
Posts: 282
Joined: Tue Mar 19, 2013 8:52 pm

Best way to 'export' to MS Word table

Post by iwbnwif »

I appreciate that this is not strictly a wxWidgets question, but I am interested if anyone here has solved a similar problem.

I have a wxGrid full of text that I would like to 'export' to a MS Word table.

So far I have considered the following:
  • Generate HTML and save as a file. This is relatively simple but inconvenient because for the user it means opening a HTML file (which Word might not do automatically) before cutting / pasting into a document;
    Generate HTML and copy to clipboard. More user friendly, user can just paste into their document but not sure if the formatting will copy across well. When I look at what Word puts on the clipboard when you copy a table in HTML, its frightening :shock:
    As above but use RTF instead of HTML. I think this is more or less a non-starter as RTF seems inherently much more complicated and the helper libraries are all but defunct;
    Use wxAutomationObject. I think this has the most promise, of course it is not cross-platform and wouldn't work with say LibreOffice, but at the moment neither of these are in my primary requirements list. The problem with this approach is that there seems to be a lack of information about using wxAutomationObject in any detail (I have looked at the one in the /samples directory. All the C++ examples I can find seem to be for C++ builder which has its own API.
So if anyone has tackled a similar problem, has some code or a tutorial / blog they can point me to I would be very happy.

My requirements for this are not too difficult, just a straightforward table with thin borders and using "Table Heading" and "Table Content" styles.
wxWidgets 3.1.2, MinGW64 8.1.0, g++ 8.1.0, Ubuntu 19.04, Windows 10, CodeLite + wxCrafter
Some people, when confronted with a GUI problem, think "I know, I'll use Eclipse RCP". Now they have two problems.
iwbnwif
Super wx Problem Solver
Super wx Problem Solver
Posts: 282
Joined: Tue Mar 19, 2013 8:52 pm

Re: Best way to 'export' to MS Word table

Post by iwbnwif »

I am going to answer my post a bit here because I found one article (unfortunately in Chinese) that gives a good insight into doing exactly what I want. The article is here http://emonkey.iteye.com/blog/1629247

In case anyone is interested this is what I have distilled so far...

Code: Select all

void MainFrame::onButtonClicked(wxCommandEvent& event)
{
    wxAutomationObject oWord, oDoc;

    if(!oWord.GetInstance(_("Word.Application")))
    {
        if (!oWord.CreateInstance(_("Word.Application")))
        {
            wxMessageBox(wxT("Can not create word application"));
            oWord.CallMethod("Word.Close");
            return;
        }
    }
    oWord.PutProperty(wxT("Visible"), true);
    // oWord.CallMethod("Documents.Add");
    oWord.GetObject(oDoc, "ActiveDocument");

  //Add Table
    wxVariant args[3];
    args[0] = oDoc.GetProperty("Paragraphs.Last.Range");
    args[1] = 30L;
    args[2] = 5L;

    oDoc.CallMethod("Tables.Add", 3, args);

    wxVariant index = oDoc.GetProperty("Tables.Count");
    wxAutomationObject oTable(oDoc.CallMethod("Tables.Item", index).GetVoidPtr());
    oTable.PutProperty("Borders.InsideLineStyle", true);// wdLineStyleSingle
    oTable.PutProperty("Borders.OutsideLineStyle", true);//

    //Add TableCellText
    wxString ar_text="Some text to go in a cell";
   for (long i = 1; i <= 30; i++ ) {
      for (long col = 1; col <= 5; col++) {
	  wxAutomationObject cell(oTable.CallMethod("Cell", i, col).GetVoidPtr());
         cell.CallMethod("Range.InsertAfter", ar_text);//cell.PutProperty("Range.Text",ar_text);
     }
  }
}
wxWidgets 3.1.2, MinGW64 8.1.0, g++ 8.1.0, Ubuntu 19.04, Windows 10, CodeLite + wxCrafter
Some people, when confronted with a GUI problem, think "I know, I'll use Eclipse RCP". Now they have two problems.
fancyivan
Experienced Solver
Experienced Solver
Posts: 80
Joined: Wed May 26, 2010 8:42 am
Location: Beijing, China
Contact:

Re: Best way to 'export' to MS Word table

Post by fancyivan »

I think it is the most common or easy way to export sth to MS Word by using wxAutomationObject.
there are 2 ways I think : A) get data from grid and put data into MS Word. B) copy, then paste

I finished a small application 2 months ago,
the requirements are:
1.show the result in a table
2.draw a chart at the same time.
3.export to Excel.(I think it is the same situation with MS Word.)

A) firstly, I tried to use wxGrid(for item 1) and wxFreeChart(for item 2),
Then use the following codes to export to Excel. it is the same with which you found in internet.

Code: Select all

wxVariant rng[1];
for(loop each row.....)
for(loop each column....)
{
   //set value to Excel
    ......
    rangeObject.CallMethod(wxT("Activate"));
    excelObject.PutProperty(wxT("ActiveCell.Value"), wxT("data data"));
}
//Then Create Chart in Excel by using VBA
it is not very easy because I need to write a lot of codes in order to update the data for my instance of wxGrid and wxFreeChart.
and also, wxGrid and wxFreeChart don't look very good. especially the chart is not beautifull.

B) then I changed my way, I directly use wxWebView in order to show Grid(divs with a little css style) and Chart(actually it is HighCharts).
it is beautifull. Then I just copy(select all elements by executing some javascripts and copy to clipboard) and then paste them into MS Excel.
here is some codes:

Code: Select all

wxAutomationObject excelObject, rangeObject;
    if (!excelObject.GetInstance(_T("Excel.Application")))
    {
        if (!excelObject.CreateInstance(_T("Excel.Application")))
        {
            wxLogMessage(wxT("Can not create Excel instance"));
            return;
        }
    }
    wxVariant rng[1];

    excelObject.CallMethod(wxT("Workbooks.Add"));
    // Hide GridLine
    excelObject.PutProperty(wxT("ActiveWindow.DisplayGridlines"), false);
//enable selectable
    m_Browser->RunScript(wxT("document.onselectstart = function(){return true;};"));
    // Write some text to the clipboard
    wxString script(wxT("text = document.getElementById(\"myTable\");\
        var range = document.body.createTextRange();\
        range.moveToElementText(text);\
        range.select();"));
    m_Browser->RunScript(script);
    m_Browser->Copy();
    m_Browser->ClearSelection();
    //disable selectable
    m_Browser->RunScript(wxT("document.onselectstart = function(){return false;};"));
    //paste
    rng[0] = wxVariant(wxT("A2"));
    excelObject.GetObject(rangeObject, wxT("ActiveSheet.Range"), 1, rng);
    rangeObject.CallMethod(wxT("Activate"));
    excelObject.CallMethod(wxT("ActiveSheet.Paste"));
Hope it can help somebody.

Tao
OS: Win7 Ultimate SP1 x64(Windows XP Pro SP3 in VirtualBox)
Compiler: MinGW32 (gcc4.8.1 + gdb7.6.1)
IDE: Code::Blocks 12.11
Lib: wxWidgets3.0.0
iwbnwif
Super wx Problem Solver
Super wx Problem Solver
Posts: 282
Joined: Tue Mar 19, 2013 8:52 pm

Re: Best way to 'export' to MS Word table

Post by iwbnwif »

Hi, thanks for an interesting message.
wxWidgets 3.1.2, MinGW64 8.1.0, g++ 8.1.0, Ubuntu 19.04, Windows 10, CodeLite + wxCrafter
Some people, when confronted with a GUI problem, think "I know, I'll use Eclipse RCP". Now they have two problems.
Post Reply