write to an excel file:
I need write data to Excel from my Qt application.
I do such way:
QAxObject* excel = new QAxObject( "Excel.Application", 0 );
excel->dynamicCall("SetVisible(bool)",true);
QAxObject *workbooks = excel->querySubObject( "Workbooks" );
QAxObject *workbook = workbooks->querySubObject( "Open(const
QString&)", "C:\\A.xls" );
QAxObject *sheets = workbook->querySubObject( "Sheets" );
QAxObject *StatSheet = sheets->querySubObject( "Item(const
QVariant&)", QVariant(QString::fromLocal8Bit("test")) );
StatSheet->dynamicCall( "Select()" );
excel->dynamicCall(" SetScreenUpdating(bool)",false);
//here I write data...It's not have a matter of principle...
excel->dynamicCall(" SetScreenUpdating(bool)",true);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
All work perfect but this must take place insensibly to user... How I
can do this?
Most office files are OLE compound files, so you should first use libole2 to
access them (OLD compound files are like small filesystems, imagine a floppy
disk image or somesuch, although they use their own filesystem not compatible
with vfat). You'll see that .xls file (like .doc, .dbs, etc) contains a few
streams (stream = file in OLE compound file terminology), one per worksheet I
assume, plus some other gibberish.
Another issue is to filter data in those streams.
You can look into KOffice filters, GNumeric and OpenOffice. I think that
GNumeric filters are the best (simplicity of code vs. completeness).
Open Ms Word, Ms excel, ppt files in QT -Linux:
need to open Ms Word, excel, powerpoint files in a QT application. The
files need to show in a widget. Is there a plugin available which can
allow the files to be opened? On windows we can do it through ActiveX
component but the application will be on Embedded linux. Even if there
is a utility on x11(desktop), please do reply as it will be of great
help. This can be customised for embedded environment.
OpenOffice and KOffice can open MS office documents (not
absolutely sure about KOffice), so maybe you should get some info on how
they do it.
Solution 1: Try to use the openoffice SDK to read and display MS office documents:
Solution 2: Koffice uses Qt and is open-source, so if you are also
writing an open-source application, you might be able to reuse some of
their code:
Solution 3: Understand the word/excel/powerpoint formats and create
custom Qt widgets which can read them (the custom widget part is
probably the easiest here)... 0.O
If you find a library to import MS office documents, it might not be to hard. Perhaps the openoffice code/SDK will help.
KOffice seems to have "import/export filters for many of the binary MS Office file formats -- .doc, .xls, .rtf.".
Note: There's also which I just discovered now.
Source code
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
Word::Application *app; try { app = new Word::Application; } catch (...) { Utils::error("Some exception raised"); return false; } Word::Document *doc = app->Documents()->Open(fileTemplate); Word::Range *rng = doc->Range(0, 200); // (1) ... Excel::Application *app; try { app = new Excel::Application; } catch (...) { Utils::error("Some exception raised"); return false; } app->SetDisplayAlerts(false); Excel::Workbook *wb = app->Workbooks()->Open(fileTemplate); // process each worksheet for (int i = 1; i <= wb->Worksheets()->Count(); ++i) { Excel::_Worksheet *ws = new Excel::_Worksheet(wb->Worksheets()->Item(i)); QList keys = substParams.keys(); for (QList::const_iterator key = keys.begin(); key != keys.end(); ++key) ws->Cells()->Replace("%" + *key + "%", "bla-bla", Excel::xlPart); // (2) delete ws; } |
Problem occurs when control flow reaches line (2) -- it gives assert "id
< 0" in qaxbase.cpp:3610 (qt_metacall). I've investigated that
problem occurs beginning with line (1), commenting it out (and all
Word-code below) "solves" the problem. Could someone tell me, what's
going on? It seems like some internal structures are altered or
something. Thanks in advance.
Problem was solved by patching dumpcpp tool to decorate type names,
interned into meta-object system, with namespace. Now it works just
fine.
Kind of interest, does Trolltech accept patches for proprietary code?
|
Source code
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
|
QAxObject* excel = new QAxObject( "Excel.Application", 0 ); QAxObject* workbooks = excel->querySubObject( "Workbooks" ); QAxObject* workbook = workbooks->querySubObject( "Open(const QString&)", exchange->getFilename() ); QAxObject* sheets = workbook->querySubObject( "Worksheets" );
QList data; //Data list from excel, each QVariantList is worksheet row
//worksheets count int count = sheets->dynamicCall("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->dynamicCall( "Count()" ).toInt(); //similarly, always returns 65535 //One of possible ways to get column count int currentColumnCount = 0; for (int col=1; col { QAxObject* cell = sheet->querySubObject( "Cells( int, int )", COLUMN_COUNT_ROW, col ); QVariant value = cell->dynamicCall( "Value()" ); if (value.toString().isEmpty()) break; else currentColumnCount = col; } columnCount = currentColumnCount;
//sheet->dynamicCall( "Calculate()" ); //maybe somewhen it's necessary, but i've found out that cell values are calculated without calling this function. maybe it must be called just to recalculate
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++) { QAxObject* cell = sheet->querySubObject( "Cells( int, int )", row, column ); QVariant value = cell->dynamicCall( "Value()" ); if (!value.toString().isEmpty() && isEmpty) isEmpty = false; dataRow.append(value); } if (isEmpty) //criteria to get out of cycle break; data->append(dataRow); } }
workbook->dynamicCall("Close()"); excel->dynamicCall("Quit()"); |
|
Source code
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
bool cMSExcelAutomation::initializeExcel97(bool isVisible) { QString msg; try { m_excel = new QAxObject(EXCEL97); if ( !m_excel ) { msg = QObject::tr("Ei saatu instantioitua Excel-oliota (%1)").arg(EXCEL97); logWriter().logMsg("cMSExcelAutomation::initializeExcel97", msg); return false; } m_excel->disableEventSink(); // Asetetaan näkyville QVariant visible(isVisible); m_excel->dynamicCall("SetVisible(bool)",visible); msg = QObject::tr("Excel-olio (%1) luotu").arg(EXCEL97); logWriter().logMsg("cMSExcelAutomation::initializeExcel97", msg); return true; } catch (...) { msg = QObject::tr("Poikkeus Excel-olion (%1) luomisen yhteydessä").arg(EXCEL97); logWriter().logMsg("cMSExcelAutomation::initializeExcel97", msg); return false; } return false; } |
阅读(3527) | 评论(0) | 转发(0) |