Lire un document Office, OpenDocument ou PDF, ou autre format riche programmatiquement en Qt / C++ / autre… comme il fallait s’y attendre, ce n’est pas de la tarte ! Apparemment, il est relativement faisable d’afficher un document PDF, Office ou LibreOffice directement via un objet Qt, ou une bibliothèque. Mais ici, je cherche à lire le contenu, afin de pouvoir en extraire des morceaux suivant un patron (vous l’aurez deviné, c’est un document de norme, dont j’aimerai extraire la liste des exigences ><).
Voici une liste des ressources que j’ai pu trouver sur le sujet. Je n’ai rien testé pour l’instant.
- Documentation Qt : Handling document formats explique le principe général. Des sous-articles sont censés explicités pour Word, Excell, Writer, …
- Handling Word, et un exemple de code avec Excel
- Handling PDF, notamment la bibliothèque poppler
- De la doc Microsoft
- Un outils Qt : OpenDocument reader / writer (LGPL)
- Un outils de KDE appelé Okular et compilé en Qt permet de lire des documents OpenDocument et autre ! En général avec KDE il y a toujours des dépendances de partout avec le reste de KDE, à voir…
- Une initiative de quelqu’un pour écrire de l’OpenDocument en Qt
- Lire le format RTf : librtf pour C/C++
Exemple de code pour lire un fichier Excel
Pompé ici, au cas où ça disparait !
QAxObject* excel = new QAxObject( "Excel.Application", 0 ); QAxObject* workbooks = excel->querySubObject( "Workbooks" ); QAxObject* workbook = workbooks->querySubObject( "Open(const QString&)", "C:\\1.xls" ); QAxObject* sheets = workbook->querySubObject( "Worksheets" ); QList<QVariantList> data; //Data list from excel, each QVariantList is worksheet row //worksheets count int count = sheets->dynamicCall("Count()").toInt(); count = sheets->property("Count").toInt(); for (int i=1; i<=count; i++) //cycle through sheets { //sheet pointer QAxObject* sheet = sheets->querySubObject( "Item( int )", i ); QAxObject* rows = sheet->querySubObject( "Rows" ); int rowCount = rows->dynamicCall( "Count()" ).toInt(); //unfortunately, always returns 255, so you have to check somehow validity of cell values QAxObject* columns = sheet->querySubObject( "Columns" ); int columnCount = columns->property("Count").toInt(); for (int row=1; row <= rowCount; row++) { QVariantList dataRow; bool isEmpty = true; //when all the cells of row are empty, it means that file is at end (of course, it maybe not right for different excel files. it's just criteria to calculate somehow row count for my file) for (int column=1; column <= columnCount; column++) { //Do something usefule here } if (isEmpty) //criteria to get out of cycle break; data.append(dataRow); } } workbook->dynamicCall("Close()"); excel->dynamicCall("Quit()");
Si besoin, pour générer la documentation :
QFile file1("c://sheet2.html"); file1.open(QIODevice::WriteOnly | QIODevice::Text); QTextStream out(&file1); out << excel->generateDocumentation(); file1.close();