Generating word documents (.doc/.odt) through C++/Qt - c++

I am using Qt 4.5.3 and Windows XP. I need my application to generate documents that contains the information that is being used and generated. The information that is being used will be just strings (QString to be more specific) and the information that is being generated will be strings and images as well.
I want documents to be a MS word document (.doc) or can be an Open Document Format (.odt) Also I want the documents to be formatted with fonts,images, tables of data, some background colors and all.
I have done the creation PDF files using QTextDocument, QTextCursor and QPrinter. But when I tried to apply the same QTextDocument for odt, I ended up with just format error.
Is there a way to generate such documents using any other libraries that use C++? How you guys use to generate such documents (.odt/.doc) in C++? Any pointers, links, examples regarding this are welcome.

I have done this through the Qt way. i.e by using ActiveQt module.
The reference documentation for MS Word can be obtained through,
MSDN documentation, which actually pointed to the VBAWD10.chm file that has the ActiveX apis for MS Word.
The Word Application can be initialized by
QAxWidget wordApplication("Word.Application");
The sub-objects of the word application can be obtained through the function,
QAxBase::querySubObject()
For e.g:
QAxObject *activeDocument = wordApplication.querySubObject("ActiveDocument");
To pass the obtained sub-object as an argument,
QVariant QAxBase::asVariant () const
Any function calls involving the word object can be called using the function using,
QAxBase::dynamicCall ()
For e.g:
activeDocument->dynamicCall("Close(void)");
After a quite good amount of struggle and few convinces, it's working fine. :)
Hope it helps for those who are all looking for similar solutions...

maybe you can use this and write to a file in odf format http://doc.trolltech.com/4.6/qtextdocumentwriter.html#supportedDocumentFormats qt does not know how to output doc docx etc but you can use com(activeQt) or some other library to write in those or other formats you need

For me, a better way of automating Office applications is importing the object model from the MS Word COM type library into the C++ project. This is very similar to the Qutlook Example for the Outlook application. You can extrapolate the technique to Excel and PowerPoint if you want, using oleview.exe to obtain the library Guids. Here is a complete project at GitHub.
The QMake project file :
QT += widgets axcontainer
CONFIG += c++11 cmdline
DEFINES += QT_DEPRECATED_WARNINGS
DUMPCPP=$$absolute_path("dumpcpp.exe", $$dirname(QMAKE_QMAKE))
TYPELIBS = $$system($$DUMPCPP -getfile {00020905-0000-0000-C000-000000000046})
isEmpty(TYPELIBS) {
message("Microsoft Word type library not found!")
REQUIRES += StackOverflow Rocks
} else {
SOURCES = main.cpp
}
The main.cpp source:
#include <QApplication>
#include <QStandardPaths>
#include <QDir>
#include "MSWORD.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Word::Application word;
if (!word.isNull()) {
word.SetVisible(false);
Word::Documents* docs = word.Documents();
Word::Document* newDoc = docs->Add();
Word::Paragraph* p = newDoc->Content()->Paragraphs()->Add();
p->Range()->SetText("Hello Word Document from Qt!");
p->Range()->InsertParagraphAfter();
p->Range()->SetText("That's it!");
QDir outDir(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation));
QVariant fileName = outDir.absoluteFilePath("wordaut.docx");
QVariant format = Word::wdFormatXMLDocument;
newDoc->SaveAs2(fileName, format);
QVariant fileName2 = outDir.absoluteFilePath("wordaut2.doc");
QVariant format2 = Word::wdFormatDocument;
newDoc->SaveAs2(fileName2, format2);
newDoc->Close();
word.Quit();
}
return 0;
}

Related

How to open a file with Qt when there is no default program for it?

There is a QDesktopServices::openUrl function in Qt which opens files with default programs, like when you want to open .docx file with Microsoft Office. However, the function will simply return 0 and do nothing if there is no default program assotiated with the file extension of the requested file. I would like Qt to show something like this instead:
A cross-platform solution would be ideal.
Is it possible with Qt?
This one works for me. But I didn't test it anywhere except my Windows 7 machine
QDesktopServices::openUrl(QUrl::fromLocalFile("D:/file"));
Try something like this. It should open the dialog you need. But on WIndows 10 it does not show the checkbox, I am not sure why.
#include <ShlObj.h>
bool openWith(const QString &filePath)
{
QString nativePath = QDir::toNativeSeparators(filePath);
OPENASINFO oi = {};
oi.pcszFile = reinterpret_cast<LPCWSTR>(nativePath.utf16());
oi.oaifInFlags = OAIF_ALLOW_REGISTRATION | OAIF_EXEC;
return SHOpenWithDialog(NULL, &oi) == S_OK;
}

How to print version of a Qt GUI application to console

I have a GUI application written using Qt Widgets. I've added versioning and I'm planning to write an update manager too. In order this to work the update manager must be able to determine the version of my app. I thought of implementing this by running my app with a version switch then parsing it's output. I did a research and I found out that Qt has some kind of built in solution for this.
Here is an example:
#include "mainwindow.h"
#include <QApplication>
#include <QCommandLineParser>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QApplication::setApplicationVersion("1.0.0");
QCommandLineParser parser;
auto versionOption = parser.addVersionOption();
parser.process(app);
if (parser.isSet(versionOption))
{
MainWindow w;
w.show();
return app.exec();
}
return 0;
}
If I launch this app with a -v or --version command line switch, I get a message box containing the version information.
I need to achieve the same, only the information should be printed to standard output. If the app is launched with the version switch it should only display the version in the console then close.
How could I print the version information to the standard console output with a GUI app?
As we cleared some points in comments let's move on. ;)
Take a look at the documentation (http://doc.qt.io/qt-5/qapplication.html#details). In the detail section you see a sane way how to properly parse and handle command line options.
And here (https://stackoverflow.com/a/3886128/6385043) you can see a possibility for writing to standard output. Notice the QDebug caveat.
In my opinion, stick to the text file. You may generate it during build with qmake using the variable VERSION, which you can also use with QApplication::setApplicationVersion(QString).

QWebEngine: print a page?

The migration from QWebKit to QWebEngine seems to be much more complicated than Qt guys claimed. With QWebKit I could print a webpage easily via
QWebView->print(&printer);
With QWebEngine class QWebEngine view does not provide a method print(). Their browser example uses a class named QWebEngineFrame which offers a method print() - but the whole QWebEngineFrame is not defined anywhere!
So my question: how do I print a page using QWebEngine?
I think the correct way to use QWebEngineView::render method because QWebEngineView is a QWidget. It accepts paint device as a first argument and you may pass QPrinter there for printing.
Update: If you can use the latest version of Qt, in Qt 5.8 a new function for printing page was added:
void QWebEnginePage::print(QPrinter *printer, FunctorOrLambda resultCallback);
Actually it first prints to temp PDF with QPrinter settings.
Here is the link to Qt docs.
You can read about this in our blog also.
I would offer following code (for a while):
QTextEdit *textEdit = new QTextEdit;
ui.myWebView->page()->toHtml([textEdit](const QString &result){ textEdit->setHtml(result); });
textEdit->print(somerinter);
textEdit->deleteLater();
Qt 5.7 includes print support in to pdf files for QWebEngine.
Use printToPdf function to export the current page in a pdf file. Example:
const QString fileName = QFileDialog::getSaveFileName(0,
tr("Save pdf"),
".",
tr("PDF Files (*.pdf)"));
if (fileName.isEmpty()) {
return;
}
ui->webView->page()->printToPdf(fileName);
QWebView->page()->print(&printer, [=](bool){});

PDFCreator will print TIFF instead of PDF

I am trying to convert a RTF document to PDF. I have this code:
// TestCOMPDF.cpp : Defines the entry point for the console application.
//
#include <windows.h>
#include <tchar.h>
#include <objbase.h>
#include <atlbase.h>
#import "MSVBVM60.DLL" rename ( "EOF", "VBEOF" ), rename ( "RGB", "VBRGB" ) //if you don't use this you will be in BIG trouble
#import "PDFCreator.exe"
int _tmain(int argc, _TCHAR* argv[])
{
CoInitialize(NULL);
{
CComPtr<PDFCreator::_clsPDFCreator> pdfObject;
HRESULT hr = pdfObject.CoCreateInstance(L"PDFCreator.clsPDFCreator");
pdfObject->cStart("/NoProcessingAtStartup", 1);
PDFCreator::_clsPDFCreatorOptionsPtr opt = pdfObject->GetcOptions();
opt->UseAutosave = 1;
opt->UseAutosaveDirectory = 1;
opt->AutosaveDirectory = "c:\\temp\\";
opt->AutosaveFormat = 0; // for PDF
opt->AutosaveFilename = "gigi13";
pdfObject->PutRefcOptions(opt);
pdfObject->cClearCache();
_bstr_t DefaultPrinter = pdfObject->cDefaultPrinter;
pdfObject->cDefaultPrinter = "PDFCreator";
hr = pdfObject->cPrintFile("c:\\temp\\RTF\\garage.rtf");
pdfObject->cPrinterStop = false;
while(true)
{
printf("sleep\n");
Sleep(1000);
if(pdfObject->cCountOfPrintjobs == 0)
break;
}
printf("done\n");
pdfObject->cPrinterStop = true;
pdfObject->cDefaultPrinter = DefaultPrinter;
}
CoUninitialize();
return 0;
}
When running this code sample instead of creating directly the PDF it prompts me with a Save dialog offering me the option to the output only with the option of choosing a TIFF file (which is not wanted). Can someone point me into the right direction or offer some suggestions?
Thanks,
Iulian
This is only a guess... I had a similar problem -- not when using PDFCreator programmatically (this is beyond my capabilities), but when using it as my standard printer to print to PDFs.
First I used it for a couple of days without any problem. Not I had installed it, but my partner. As I said... it just worked, and created beautiful PDFs.
Then, somehow, someone on our home computer (we are 3 different persons using it) must have changed the setting (maybe inadvertedly) to make it output TIFF instead of PDFs. For me, my default printer was named "PDFcreator" and it confused the hell out of me why it suddenly wanted to create TIFFs.
Meanwhile I've poked a lot in the user interface of all its settings, and learned to know where to look if something goes wrong.
The newest version in its lefthand treeview panel lists an item named "Save". If you select it, you can configure default filename conventions as well as "Standard save format". In my case in the dropdown listview there was "TIFF" selected instead of "PDF".
Looking at your code, you are somehow calling PDFCreator.exe (I don't understand the details, but I can see this string in your code). My bet would go towards this: somehow, the user account which your code uses to run under has his Standard save format set to TIFF. It may be that you look at the printer settings (on my Windows XP, I just type control printers, and rightclick the PDFCreator printername to select Properties...) and find nothing suspicious.
However, PDFcreator stores its settings for each user into a different location, probably in %userprofile%\local settings\temp\pdfcreator\..., or even in the registry...

Using Qt's XML library for simple operation

I basically want to use the XML parser from Qt in my existing project. I have only used Qt once before, and that was with Qt Designer, and I am not having much luck finding anything on Google about how to just use the XML library.
I have downloaded a web page that has one large list, and I want to parse it and add each list item to a c++ list. I found this sample code on Ubuntu forums...
http://www.uluga.ubuntuforums.org/showpost.php?p=9112973&postcount=6
I want to use that except I need to know what exactly I need to add to the project to get access to it.
One other small question is QDomDocument seems to be for files (makes sense) but I have the XML in a string. What part of the XML library works for contents of a string?
The following code should give you a quick view of what to do with Qt XML features for what you need.
#include <list>
#include <QDomDocument>
#include <QFile>
int main()
{
QString filename("myfile.xml");
std::list<QString> result;
int errorLine, errorColumn;
QString errorMsg;
QFile modelFile(filename);
QDomDocument document;
if (!document.setContent(&modelFile, &errorMsg, &errorLine, &errorColumn))
{
QString error("Syntax error line %1, column %2:\n%3");
error = error
.arg(errorLine)
.arg(errorColumn)
.arg(errorMsg);
return false;
}
QDomElement rootElement = document.firstChild().toElement();
for(QDomNode node = rootElement.firstChild();
!node .isNull();
node = node .nextSibling())
{
QDomElement element = node.toElement();
result.push_back(element.tagName());
}
return 0;
}
UPDATE
I believe you only need core Qt library as well as XML library.
You have to add QtXml in the .pro file and include QDomDocument
or only include QDomDocument like
include <QtXml/QDomDocument>