Generating docx / Communicating with Word add-in
-
My main story is that I need to generate a document (preferably Word, although Open Document Format would be a viable alternative). My application is written with Qt 4.8, is running on Windows, and I can assume that the user also has Word installed (if they need to generate documents at all).
Through some research, I have pretty much decided to write a Word Add-in using .NET (unless a better alternative pops up). The alternatives I have looked at:
- Generating ODT using QTextDocument - lacks some things I need (e.g. border styles for tables, page headers and footers)
- Alternative dedicated C++ libraries for generating docx or ODT. I have not found one that still seems to be maintained.
- Using capabilities of KOffice / LibreOffice / OpenOffice to generate ODT. Here, I have huge doubts that I can extract a small part that does what I want. And forcing the user to basically install a whole office application just to generate a document is too much.
- Generating docx format from scratch (after all, it's just XML, right?) - just...no.
So my current idea is to write a Word Add-in using .NET, and transfer the data between my Qt tool using an intermediate file format (note that my application and Word don't necessarily run at the same time - maybe the user wants to generate the document, and only hour later import it using the add-in).
The Add-in would generate the real docx file based on the data it got.How would I best and easiest achieve the data transfer?
One suggestion I had was using JSON for that. However, Qt 4 does not have a builtin JSON writer (and much as I would love to, I am not at liberty to upgrade the application to Qt 5).
-
@Asperamanca
It's a shame you cannot find some existing C++ library for this.I don't know whether this might help you, but: My application is written in Python. It has to read & write
docx
files. We are finding it works with either Word or LibreOffice documents. For Python we are usingpython-docx
--- https://python-docx.readthedocs.io/en/latest/, https://github.com/python-openxml/python-docx. It's a pretty simple, low-level interface, so not sure about all the features you might want, but it might be worth a look for ideas about how it parses the file. Note that it works purely against the file, so you don't need Word or whatever actually running as it does its work. -
You overlooked 2 options that, in my opinion, are the most promising:
- Use ActiveX through Qt to access MS word and let it do the job.
- link to
Microsoft.Office.Tools.Word.dll
using C++/CLI and useMicrosoft::Office::Tools::Word
directly in your C++ program, no need to build an addin
P.S.
Generating docx format from scratch (after all, it's just XML, right?) - just...no.
Wrong. The ISO standard for that format is more than 6000 pages. I agree with you, just stay away
P.P.S.
I'm fairly confident there are pure C++ commercial libraries for this -
@VRonin said in Generating docx / Communicating with Word add-in:
You overlooked 2 options that, in my opinion, are the most promising:
- Use ActiveX through Qt to access MS word and let it do the job.
- link to
Microsoft.Office.Tools.Word.dll
using C++/CLI and useMicrosoft::Office::Tools::Word
directly in your C++ program, no need to build an addin
P.S.
Generating docx format from scratch (after all, it's just XML, right?) - just...no.
Wrong. The ISO standard for that format is more than 6000 pages. I agree with you, just stay away
P.P.S.
I'm fairly confident there are pure C++ commercial libraries for thisI have also looked at the ActiveX option, but forgot to mention that. I have to say, I am a bit traumatized from the past on that (using Office via ActiveX from Visual Basic). It was always a hassle, you had to test every Office version you wanted to support separately (lots of virtual machines), and the system easily broke down. I'm not saying I won't have the problem with one of the other solutions, but at least there is hope :-)
Using the DLL via C++/CLI sounds more promising - I'll certainly look into that.
And if there are commercial libraries out there, they don't do a good job on the search engines. I've spent a couple of hours using two different search engines, and did not come across a single commercial library.
-
@Asperamanca
Just checking:http://docxfactory.com/
https://github.com/xceedsoftware/DocX
https://www.nuget.org/packages/DocX/
https://code.msdn.microsoft.com/office/How-programmatically-0b9e250a/view/Discussions#contentYou'll probably say you've looked at these, but just in case... :)
-
@JNBarchan said in Generating docx / Communicating with Word add-in:
@Asperamanca
Just checking:http://docxfactory.com/
https://github.com/xceedsoftware/DocX
https://www.nuget.org/packages/DocX/
https://code.msdn.microsoft.com/office/How-programmatically-0b9e250a/view/Discussions#contentYou'll probably say you've looked at these, but just in case... :)
Well, I was specifically looking for libraries to generate my document directly from (unmanged) C++. Once I open the .NET door, I certainly have multiple options.
-
@Asperamanca
Ah, well, http://docxfactory.com/ is non-.NET C++. -
@JNBarchan said in Generating docx / Communicating with Word add-in:
@Asperamanca
Ah, well, http://docxfactory.com/ is non-.NET C++.Right. Last entry in change log: 2015 :-(
-
@Asperamanca
Yep, I know. Might still give you some ideas if you decide to write stuff for yourself. Best of luck! -
Thank you all for your inputs. I further researched and discussed this, and this is the solution I am exploring further:
- Create a DLL with Qt and Common Runtime Support (/clr option)
- Write interface of DLL with unmanaged C++ classes
- Include C++/CLI classes to access .NET libraries
- Use DocumentFormat.OpenXml package to create and write document
- Use QLibary in my application to access that DLL and provide the necessary data over the DLL interface
I have a prototype where a normal Qt application calls the DLL, hands over a QString, and the DLL creates a docx file containing that QString.
I see the following advantages with this solution:
- No extra executable (just a DLL that needs to be copied with my application, and that doesn't need to be registered)
- No need for process-to-process data transfer
- Ability to share source files between application and DLL (e.g. data structures)
Open questions:
- Should I choose Microsoft.Office.Tools.Word instead of DocumentFormat.OpenXml? What are advantages and disadvantages?
- Under what circumstances is the DocumentFormat.OpenXml package available on a client machine? In what version?
- Can I expect any issues handing over complex classes via DLL interface? (The fact that QString works makes it look like that should work)
Useful links I found during research:
- How to: Migrate to /clr - https://msdn.microsoft.com/en-us/library/ms173265.aspx
- On how to use interface class to make class members accessible via DLL interface - https://stackoverflow.com/questions/43782576/accessing-c-class-member-functions-of-a-dll-in-qt#43799037 and https://stackoverflow.com/questions/26234327/qlibrary-import-a-class#26235934
- Learn C++/CLI in less than 10 minutes - https://www.codeproject.com/articles/19354/quick-c-cli-learn-c-cli-in-less-than-minutes
- Office code samples - https://code.msdn.microsoft.com/office/
- How to: Open and add text to a word processing document (Open XML SDK) - https://msdn.microsoft.com/en-us/library/office/ff478255.aspx
- How to: Create a word processing document by providing a file name (Open XML SDK) - https://msdn.microsoft.com/en-us/library/office/ff478190.aspx
- Solution to a trap I fell into - https://stackoverflow.com/questions/12743152/openxml-c-cli#12746349
- Convert std::string to System::String^ - https://social.msdn.microsoft.com/Forums/vstudio/en-US/e7711471-5b3c-489f-9dad-32b37058a689/convert-stdstring-to-systemstring?forum=vclanguage
-
@Asperamanca said in Generating docx / Communicating with Word add-in:
Should I choose Microsoft.Office.Tools.Word instead of DocumentFormat.OpenXml? What are advantages and disadvantages?
They do 2 different things. the first is a "pipe" into MS word, the second is a document creator
Under what circumstances is the DocumentFormat.OpenXml package available on a client machine? In what version?
As far as I'm aware .Net is the only requirement for that namespace
-
@Asperamanca
As @VRonin says, "Microsoft.Office.Tools.Word
is a "pipe" into MS word,".Your original spec said:
(note that my application and Word don't necessarily run at the same time - maybe the user wants to generate the document, and only hour later import it using the add-in)
Depends exactly what you mean by that, but
Microsoft.Office.Tools.Word
will "invoke" Word to do the work, even though it may be invisible rather than interactive. -
Thanks, the two of you. Document creator sounds like what I need. The lighter, the better.
-
I would like to inform you that Aspose.Words for C++ is an advanced Word Document Processing API to perform a wide range of processing tasks. API provides document formatting, manipulation, mail merge, watermarking and much more capabilities directly within your own C++ applications without requiring Microsoft Word. API supports most of the Microsoft Word formats for processing. You can even integrate this native C++ API within your Qt application.
I am sharing here an example cmake project which uses Qt and Aspose.Words for C++. Then please do the following steps:
- Download and install cmake
- Download and unpack Aspose.Words for C++ library
- Copy Aspose.Words.Cpp and CodePorting.Native.Cs2Cpp_vc14_20.3 folders next to CMakeLists.txt file
- Run the following command from command line:
cd qthw cmake -G "Visual Studio 15 2017" -Thost=x64 -Ax64 -S . -B build -D"Qt5_DIR=<path-to-qt5>"
path-to-qt5
should be something like -x:\QT\5.14.2\msvc2017_64\lib\cmake\Qt5
- path to folder withQt5Config.cmake
fileIt should create Visual Studio 2017 Solution with a proper setup for Qt and Aspose.Words for C++.