Click here to Skip to main content
Click here to Skip to main content

How to Read and Write Excel Files in C++ via ADO

By , 10 Nov 2010
 

Introduction

Sometimes software developers need to export some data to Excel format or read some cells from Excel file. One way to do it without Excel automation is interaction with ADO. In this case, Excel files are treated as database. This method doesn't require Microsoft Excel and quickly enough, but it doesn't support formatting and formulas.

Connection Strings

There are two types of connection strings. First for binary format (xls):

Provider=Microsoft.JET.OLEDB.4.0;Data Source=data.xls;Extended Properties="Excel 8.0"

Second for XML format (xlsx):

Provider=Microsoft.ACE.OLEDB.12.0;Data Source=data.xlsx;
Extended Properties="Excel 12.0 Xml" 

If input file doesn't have a header with column names then add ";HDR=NO" in extended properties.

Writing

First create a Connection object:

TESTHR(pCon.CreateInstance(__uuidof(Connection)));
TESTHR(pCon->Open(connStr, "", "", NULL)); 

Afterwards, create Command object and table. Note that name of table is name of sheet:

TESTHR(pCmd.CreateInstance(__uuidof(Command)));
pCmd->ActiveConnection = pCon;       
pCmd->CommandText = "CREATE TABLE MySheet
    (A int, B varchar, C int, D int, E int, F int, G int, H int, I int, J varchar)";   
pCmd->Execute(NULL, NULL, adCmdText); 

Create Recordset and add records with values:

TESTHR(pRec.CreateInstance(__uuidof(Recordset)));
pRec->Open("SELECT * FROM MySheet", _variant_t((IDispatch*)pCon), 
	adOpenKeyset, adLockOptimistic, adCmdText);

for(int i = 0; i < writeRows; ++i)
{
    TESTHR(pRec->AddNew());

    char str[11] = {0}; for(int j = 0; j < 10; ++j) str[j] = 'a' + (rand() % 26);

    pRec->Fields->GetItem("A")->Value = _variant_t(i);            
    pRec->Fields->GetItem("B")->Value = _variant_t(str);            
    pRec->Fields->GetItem("C")->Value = _variant_t(i);
    pRec->Fields->GetItem("D")->Value = _variant_t(i);
    pRec->Fields->GetItem("E")->Value = _variant_t(i);
    pRec->Fields->GetItem("F")->Value = _variant_t(i);
    pRec->Fields->GetItem("G")->Value = _variant_t(i);
    pRec->Fields->GetItem("H")->Value = _variant_t(i);
    pRec->Fields->GetItem("I")->Value = _variant_t(i);
    pRec->Fields->GetItem("J")->Value = _variant_t(str);            
}
TESTHR(pRec->Update());
TESTHR(pRec->Close());

Reading

Create and open Recordset:

TESTHR(pRec.CreateInstance(__uuidof(Recordset)));       
TESTHR(pRec->Open("SELECT * FROM [Sheet1$]", connStr, 
	adOpenStatic, adLockOptimistic, adCmdText));

If name of sheet is unknown, then it's possible to look it up by index:

TESTHR(pCon.CreateInstance(__uuidof(Connection)));
TESTHR(pCon->Open(connStr, "", "", NULL));
    
pSchema = pCon->OpenSchema(adSchemaTables);      

for(int i = 0; i < sheetIndex; ++i) pSchema->MoveNext();

std::string sheetName = 
	(char*)(_bstr_t)pSchema->Fields->GetItem("TABLE_NAME")->Value.bstrVal;

Extract values of cells:

while(!pRec->adoEOF)
{
    for(long i = 0; i < pRec->Fields->GetCount(); ++i)
    {
        if(i > 0) stream << ";";                    
        _variant_t v = pRec->Fields->GetItem(i)->Value;
        if(v.vt == VT_R8)                                           
            stream << v.dblVal;
        if(v.vt == VT_BSTR)
            stream << (char*)(_bstr_t)v.bstrVal;                                
    }                                    
    stream << std::endl;
    pRec->MoveNext();
} 

History

  • 10th November, 2010: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Dmytro Skrypnyk
Software Developer
Ukraine Ukraine
Member
Author of LibXL library - a simple way for access to Excel files.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionProblem reading other data types than strings PinmemberGerald Schade22 Jan '13 - 13:15 
Thank You for the very good code!
But, as kaskavalci mentioned, I didn't succeed in reading non-string-types from an excel sheet.
The variant type which was returned was "0" ("VT_EMPTY"), and in none of the raw members of the variant anything meaningful appeared. Additionally, reading like this:
long nr = pRec->Fields->GetItem(i)->Value;
or
float nr = pRec->Fields->GetItem(i)->Value;
returned only "0" as result in those cases.
Any hint?
Thank You in advance, Gerald
Questiongood code Pinmemberzhylei13 Jul '12 - 22:12 
it is so nice
QuestionHow to access a specific cell? PinmemberSamerW7 Jun '12 - 7:41 
For example, how would I access cell A12 using the code above?
 
Thanks
GeneralMy vote of 5 Pinmemberjohn_172616 Jan '12 - 10:17 
Needed "Excel 12.0 Xml"
QuestionQuestion about how to use this code [modified] PinmemberMember 848617913 Dec '11 - 22:35 
Hi
1. i have an excel with many sheets and
 
i want to use some code in order to read the numbers of the above excel and put them into variables.
 
I also want to write some numbers to another excel.
 

How can i use this code?
i cant understand from the example..
 

 

Thank you

modified 14 Dec '11 - 4:46.

GeneralMy vote of 4 Pinmemberkaskavalci11 Oct '11 - 9:19 
you might have mentioned about type predicting algorithm. if we have different types of cells in one column, in this case we lose some data.
GeneralMy vote of 5 PinmemberCholo16 Nov '10 - 5:46 
Simple and useful
GeneralWrite without header PinmemberWeiyou Mao12 Nov '10 - 7:29 
Thanks for sharing the code. It works very well and I voted 5. I have a question: how to write/generate the datasheet without the header. Say you have two columns, one for strings and another for numbers. In this case you normally don't need a header at the top. Do we have to have a header in order to use ADO?
GeneralRe: Write without header PingroupDmytro Skrypnyk12 Nov '10 - 10:01 
GeneralGood! PinmemberPaul Belikian11 Nov '10 - 14:01 
Thanks for the article Dmytro. LibXL is an awesome product by the way! Big Grin | :-D
GeneralMy vote of 5 PinmemberWeiyou Mao11 Nov '10 - 11:50 
It works and fast.
Generalspeed PinmemberNick Gorlov10 Nov '10 - 20:06 
not bad, bud did you compare the processing time in your variant with the standard olb-file usage? I want to know how fast is your variant.
GeneralRe: speed PingroupDmytro Skrypnyk10 Nov '10 - 20:33 
Generalgood Pinmemberdjzbj10 Nov '10 - 17:54 
very sample.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130516.1 | Last Updated 10 Nov 2010
Article Copyright 2010 by Dmytro Skrypnyk
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid