BasicExcel - 一个可读写Microsoft Excel的类

VC++操作 Excel 的方法总结


 作者 Yap Chun Wei 2002年发布     CSpreadSheet   类,采用 ODBC 方式,必须依赖于 Office 是否安装;2006年 发布 BasicExcel类,直接解析 Excel 格式

翻译来源:https://www.codeproject.com/Articles/13852/BasicExcel-A-Class-to-Read-and-Write-to-Microsoft

读取和写入Microsoft Excel的类

介绍

4年多前,2001年12月,我发布了CSpreadSheet,它能够读写Microsoft Excel。那个类比较受欢迎。然而,它有一些缺陷,如标题行的必要性,无法读取单元格作为数字等。这些都是依赖于ODBC驱动程序的结果。对ODBC驱动程序的依赖也意味着该类在Unix / Linux环境中不可用。

因此,大概在3年前,我想替换CSpreadSheet 一个可以读取和写入本机Excel格式的类。这将允许该类在Windows以外的环境中使用。它还将使用户能够将数字和字符串读取和写入电子表格。但是,由于Excel文件被保存为复合文件,这并不容易。因此,我必须先写一个类来读写复合文件,我已经完成了。(当我有时间正确地记录该类并为其编写文章时,将会被发布)。同时,该类实际上包含在这个包中)。在我写了类来读写复合文件之后,我开始使用从OpenOffice项目获得的Excel文件格式的信息来写入类来读写Excel文件。唉,

上周,我的工作承诺缓解了,我突然想起了我在3年前写的Excel课程。我想完成这个项目,但是我认为3年后,肯定有人已经完成了类似的项目。所以我在SourgeForge上快速搜索了。令我失望的是,没有这样的项目!所以我决定继续这个项目。我很快看了我的未完成的代码来熟悉自己,并开始写作。现在终于完成了,我向你呈现BasicExcel

在我们深入研究之前,我们来BasicExcel看看它的局限性。这是BasicExcel 一个理由。

  1. 它不支持格式化
  2. 它不支持公式
  3. 它不支持图表
  4. 它不支持Unicode UTF-32
  5. 它不支持...

其实它不支持Excel的很多奇特的功能。它是一个基本的类,用于读写简单的东西,如数字和字符串到电子表格。所以也许最好列出它支持的东西。

  1. 读写数字(整数,实数)和字符串(ANSI,UTF16)
  2. 添加工作表
  3. 重命名工作表
  4. 删除工作表
  5. 获取工作表的名称

就是这样 正如你所看到的,BasicExcel 真的是基本的,但即使在现在的形式下,它比以前更有能力CSpreadSheet。然而,虽然它的功能是基本的,但编程并不是基本的。需要大量的代码来读写复合文件,并以原生Excel格式进行读写。因此,总线数BasicExcel 超过6000。

使用代码

我应该列出你应该知道使用的三个类的功能BasicExcel。接下来是一个示例代码。

BasicExcel类

void New(int sheets=3) 创建一个包含给定数量的电子表格(最少1个)的新Excel工作簿。
bool Load(const char* filename) 从文件加载Excel工作簿。
bool Save() 将当前Excel工作簿保存到打开的文件。
bool SaveAs(const char* filename) 将当前Excel工作簿保存到文件。
size_t GetTotalWorkSheets() 当前Excel工作簿中Excel工作表的总数。
BasicExcelWorksheet* GetWorksheet(size_t sheetIndex) 在给定索引处获取指向Excel工作表的指针。索引从0如果索引无效返回。
BasicExcelWorksheet* GetWorksheet(const char* name) 获取指向给定ANSI名称的Excel工作表的指针。如果没有给定名称的Excel工作表返回。
BasicExcelWorksheet* GetWorksheet(const wchar_t* name) 获取指向已提供Unicode名称的Excel工作表的指针。如果没有给定名称的Excel工作表返回。
BasicExcelWorksheet* AddWorksheet(int sheetIndex=-1) 将新的Excel工作表添加到给定的索引。给工作表的名称是SheetX,其中X是从1开始的数字。索引从0。如果工作表被添加到最后一个位置sheetIndex == -1。如果成功,返回指向工作表的指针,否则。
BasicExcelWorksheet* AddWorksheet(const char* name, int sheetIndex=-1) 将给定的ANSI名称添加到给定索引的新Excel工作表。索引从0。如果工作表被添加到最后一个位置sheetIndex == -1。如果成功,返回指向工作表的指针,否则返回0。
BasicExcelWorksheet* AddWorksheet(const wchar_t* name, int sheetIndex=-1) 将给定的Unicode名称添加到给定索引的新Excel工作表。索引从0。如果工作表被添加到最后一个位置sheetIndex == -1。如果成功,返回指向工作表的指针,否则返回0。
bool DeleteWorksheet(size_t sheetIndex) 删除给定索引的Excel工作表。索引从0true 如果成功返回,false 否则。
bool DeleteWorksheet(const char* name) 删除给出ANSI名称的Excel工作表。true 如果成功返回,false 否则。
bool DeleteWorksheet(const wchar_t* name) 删除给出Unicode名称的Excel工作表。true 如果成功返回,false 否则。
char* GetAnsiSheetName(size_t sheetIndex) 在给定索引处获取工作表名称。索引从00如果名称为Unicode格式则返回。
wchar_t* GetUnicodeSheetName(size_t sheetIndex) 在给定索引处获取工作表名称。索引从00如果名称为ANSI格式,则返回。
bool GetSheetName(size_t sheetIndex, char* name) 在给定索引处获取工作表名称。索引从0false 如果名称为Unicode格式则返回。
bool GetSheetName(size_t sheetIndex, wchar_t* name) 在给定索引处获取工作表名称。索引从0开始。false 如果名称为ANSI格式,则返回。
bool RenameWorksheet(size_t sheetIndex, const char* to) 将给定索引的Excel工作表重命名为给定的ANSI名称。索引从0true 如果成功返回,false 否则。
bool RenameWorksheet(size_t sheetIndex, const wchar_t* to) 将给定索引处的Excel工作表重命名为给定的Unicode名称。索引从0true如果成功返回,false 否则。
bool RenameWorksheet(const char* from, const char* to) 重命名将ANSI名称赋给另一个ANSI名称的Excel工作表。true 如果成功返回,false 否则。
bool RenameWorksheet(const wchar_t* from, const wchar_t* to) 重命名将Unicode名称指定给另一个Unicode名称的Excel工作表。true 如果成功返回,false 否则。

BasicExcelWorksheet类

char* GetAnsiSheetName() 获取当前工作表名称。0如果名称为Unicode格式则返回。
wchar_t* GetUnicodeSheetName() 获取当前工作表名称。0如果名称为ANSI格式,则返回。
bool GetSheetName(char* name) 获取当前工作表名称。false 如果名称为Unicode格式则返回。
bool GetSheetName(wchar_t* name) 获取当前工作表名称。false 如果名称为ANSI格式,则返回。
bool Rename(const char* to) 将当前Excel工作表重命名为另一个ANSI名称。true 如果成功返回,false 否则。
bool Rename(const wchar_t* to) 将当前Excel工作表重命名为另一个Unicode名称。true 如果成功返回,false 否则。
void Print(ostream& os, char delimiter=',', char textQualifier='\0') 将整个工作表打印到输出流中,使用定义的分隔符分隔每列,并使用定义的分隔符和封闭文本textQualifiertextQualifier 如果不希望有任何文本限定符,请留下参数。
size_t GetTotalRows() 当前Excel工作表中的总行数。
size_t GetTotalCols() 当前Excel工作表中的列数总数。
BasicExcelCell* Cell(size_t row, size_t col) 返回指向Excel单元格的指针。行和列从...开始0如果行超过65535或列超过255则返回。
bool EraseCell(size_t row, size_t col) 擦除单元格的内容 行和列从...开始0。如果行或列超出范围true false则返回。

BasicExcelCell类

int Type() const 获取存储在当前Excel单元格中的值的类型。返回以下枚举之一:UNDEFINEDINTDOUBLESTRINGWSTRING
bool Get(int& val) const 获得integer 价值 false 如果单元格不包含,则返回integer
bool Get(double& val) const 获得一个double 值 false 如果单元格不包含a则返回double
bool Get(char* str) const 获取ANSI字符串。false 如果单元格不包含ANSI,则返回string
bool Get(wchar_t* str) const 获取Unicode字符串。false 如果单元格不包含Unicode,则返回string
size_t GetStringLength() ANSI或Unicode字符串的返回长度(不包括null 字符)。
int GetInteger() const 获得integer 价值 0如果单元格不包含,则返回integer
double GetDouble() const 获得一个double 值 0.<code>0如果单元格不包含a,则返回</ code /> double
const char* GetString() const 获取ANSI string0如果单元格不包含ANSI,则返回string
const wchar_t* GetWString() const 获取的统一string0如果单元格不包含Unicode,则返回string
ostream& operator<<(ostream& os, const BasicExcelCell& cell) 打印单元格输出stream。如果单元格未定义,则打印空字符。
void Set(int val) 将当前Excel单元格的内容设置为integer
void Set(double val) 将当前Excel单元格的内容设置为a double
void Set(const char* str) 将当前Excel单元格的内容设置为ANSI string
void Set(const wchar_t* str) 将当前Excel单元格的内容设置为Unicode string。
void SetInteger(int val) 将当前Excel单元格的内容设置为integer
void SetDouble(double val) 将当前Excel单元格的内容设置为a double
void SetString(const char* str) 将当前Excel单元格的内容设置为ANSI string
void SetWString(const wchar_t* str) 将当前Excel单元格的内容设置为Unicode string
void EraseContents() 擦除当前Excel单元格的内容。将类型设置为UNDEFINED

#include "BasicExcel.hpp"
using namespace YExcel;

int main(int argc, char* argv[])
{
BasicExcel e;

// Load a workbook with one sheet, display its contents and
// save into another file.
e.Load(example1.xls”);
BasicExcelWorksheet* sheet1 = e.GetWorksheet(Sheet1”);
if (sheet1)
{
size_t maxRows = sheet1->GetTotalRows();
size_t maxCols = sheet1->GetTotalCols();
cout << Dimension of " << sheet1->GetAnsiSheetName() <<
" (” << maxRows << ", " << maxCols << )” << endl;

printf(<span class="code-string" style="border:0px;color:rgb(128,0,128);">"</span><span class="code-string" style="border:0px;color:rgb(128,0,128);"> "</span>);
<span class="code-keyword" style="border:0px;color:rgb(0,0,255);">for</span> (<span class="code-sdkkeyword" style="border:0px;color:rgb(51,153,153);">size_t</span> c=<span class="code-digit" style="border:0px;color:rgb(0,0,128);">0</span>; c&lt;maxCols; ++c) printf(<span class="code-string" style="border:0px;color:rgb(128,0,128);">"</span><span class="code-string" style="border:0px;color:rgb(128,0,128);">%10d"</span>, c+1);
cout &lt;&lt; endl;

<span class="code-keyword" style="border:0px;color:rgb(0,0,255);">for</span> (<span class="code-sdkkeyword" style="border:0px;color:rgb(51,153,153);">size_t</span> r=<span class="code-digit" style="border:0px;color:rgb(0,0,128);">0</span>; r&lt;maxRows; ++r)
{
  printf(<span class="code-string" style="border:0px;color:rgb(128,0,128);">"</span><span class="code-string" style="border:0px;color:rgb(128,0,128);">%10d"</span>, r+1);
  <span class="code-keyword" style="border:0px;color:rgb(0,0,255);">for</span> (<span class="code-sdkkeyword" style="border:0px;color:rgb(51,153,153);">size_t</span> c=<span class="code-digit" style="border:0px;color:rgb(0,0,128);">0</span>; c&lt;maxCols; ++c)
  {
    BasicExcelCell* cell = sheet1-&gt;Cell(r,c);
    <span class="code-keyword" style="border:0px;color:rgb(0,0,255);">switch</span> (cell-&gt;Type())
    {
      <span class="code-keyword" style="border:0px;color:rgb(0,0,255);">case</span> BasicExcelCell::UNDEFINED:
        printf(<span class="code-string" style="border:0px;color:rgb(128,0,128);">"</span><span class="code-string" style="border:0px;color:rgb(128,0,128);"> "</span>);
        <span class="code-keyword" style="border:0px;color:rgb(0,0,255);">break</span>;

      <span class="code-keyword" style="border:0px;color:rgb(0,0,255);">case</span> BasicExcelCell::INT:
        printf(<span class="code-string" style="border:0px;color:rgb(128,0,128);">"</span><span class="code-string" style="border:0px;color:rgb(128,0,128);">%10d"</span>, cell-&gt;GetInteger());
        <span class="code-keyword" style="border:0px;color:rgb(0,0,255);">break</span>;

      <span class="code-keyword" style="border:0px;color:rgb(0,0,255);">case</span> BasicExcelCell::DOUBLE:
        printf(<span class="code-string" style="border:0px;color:rgb(128,0,128);">"</span><span class="code-string" style="border:0px;color:rgb(128,0,128);">%10.6lf"</span>, cell-&gt;GetDouble());
        <span class="code-keyword" style="border:0px;color:rgb(0,0,255);">break</span>;

      <span class="code-keyword" style="border:0px;color:rgb(0,0,255);">case</span> BasicExcelCell::STRING:
        printf(<span class="code-string" style="border:0px;color:rgb(128,0,128);">"</span><span class="code-string" style="border:0px;color:rgb(128,0,128);">%10s"</span>, cell-&gt;GetString());
        <span class="code-keyword" style="border:0px;color:rgb(0,0,255);">break</span>;

      <span class="code-keyword" style="border:0px;color:rgb(0,0,255);">case</span> BasicExcelCell::WSTRING:
        wprintf(L<span class="code-string" style="border:0px;color:rgb(128,0,128);">"</span><span class="code-string" style="border:0px;color:rgb(128,0,128);">%10s"</span>, cell-&gt;GetWString());
        <span class="code-keyword" style="border:0px;color:rgb(0,0,255);">break</span>;
    }
  }
  cout &lt;&lt; endl;
}

}
cout << endl;
e.SaveAs(example2.xls”);

// Create a new workbook with 2 worksheets and write some contents.
e.New(2);
e.RenameWorksheet(Sheet1”, Test1”);
BasicExcelWorksheet* sheet = e.GetWorksheet(Test1”);
BasicExcelCell* cell;
if (sheet)
{
for (size_t c=0; c<4; ++c)
{
cell = sheet->Cell(0,c);
cell->Set((int)c);
}

cell = sheet-&gt;Cell(<span class="code-digit" style="border:0px;color:rgb(0,0,128);">1</span>,<span class="code-digit" style="border:0px;color:rgb(0,0,128);">3</span>);
cell-&gt;SetDouble(<span class="code-digit" style="border:0px;color:rgb(0,0,128);">3</span>.<span class="code-digit" style="border:0px;color:rgb(0,0,128);">141592654</span>);

sheet-&gt;Cell(<span class="code-digit" style="border:0px;color:rgb(0,0,128);">1</span>,<span class="code-digit" style="border:0px;color:rgb(0,0,128);">4</span>)-&gt;SetString(<span class="code-string" style="border:0px;color:rgb(128,0,128);">"</span><span class="code-string" style="border:0px;color:rgb(128,0,128);">Test str1"</span>);
sheet-&gt;Cell(<span class="code-digit" style="border:0px;color:rgb(0,0,128);">2</span>,<span class="code-digit" style="border:0px;color:rgb(0,0,128);">0</span>)-&gt;SetString(<span class="code-string" style="border:0px;color:rgb(128,0,128);">"</span><span class="code-string" style="border:0px;color:rgb(128,0,128);">Test str2"</span>);
sheet-&gt;Cell(<span class="code-digit" style="border:0px;color:rgb(0,0,128);">2</span>,<span class="code-digit" style="border:0px;color:rgb(0,0,128);">5</span>)-&gt;SetString(<span class="code-string" style="border:0px;color:rgb(128,0,128);">"</span><span class="code-string" style="border:0px;color:rgb(128,0,128);">Test str1"</span>);

sheet-&gt;Cell(<span class="code-digit" style="border:0px;color:rgb(0,0,128);">4</span>,<span class="code-digit" style="border:0px;color:rgb(0,0,128);">0</span>)-&gt;SetDouble(<span class="code-digit" style="border:0px;color:rgb(0,0,128);">1</span>.<span class="code-digit" style="border:0px;color:rgb(0,0,128);">1</span>);
sheet-&gt;Cell(<span class="code-digit" style="border:0px;color:rgb(0,0,128);">4</span>,<span class="code-digit" style="border:0px;color:rgb(0,0,128);">1</span>)-&gt;SetDouble(<span class="code-digit" style="border:0px;color:rgb(0,0,128);">2</span>.<span class="code-digit" style="border:0px;color:rgb(0,0,128);">2</span>);
sheet-&gt;Cell(<span class="code-digit" style="border:0px;color:rgb(0,0,128);">4</span>,<span class="code-digit" style="border:0px;color:rgb(0,0,128);">2</span>)-&gt;SetDouble(<span class="code-digit" style="border:0px;color:rgb(0,0,128);">3</span>.<span class="code-digit" style="border:0px;color:rgb(0,0,128);">3</span>);
sheet-&gt;Cell(<span class="code-digit" style="border:0px;color:rgb(0,0,128);">4</span>,<span class="code-digit" style="border:0px;color:rgb(0,0,128);">3</span>)-&gt;SetDouble(<span class="code-digit" style="border:0px;color:rgb(0,0,128);">4</span>.<span class="code-digit" style="border:0px;color:rgb(0,0,128);">4</span>);
sheet-&gt;Cell(<span class="code-digit" style="border:0px;color:rgb(0,0,128);">4</span>,<span class="code-digit" style="border:0px;color:rgb(0,0,128);">4</span>)-&gt;SetDouble(<span class="code-digit" style="border:0px;color:rgb(0,0,128);">5</span>.<span class="code-digit" style="border:0px;color:rgb(0,0,128);">5</span>);

sheet-&gt;Cell(<span class="code-digit" style="border:0px;color:rgb(0,0,128);">4</span>,<span class="code-digit" style="border:0px;color:rgb(0,0,128);">4</span>)-&gt;EraseContents();

}

sheet = e.AddWorksheet(Test2”, 1);
sheet = e.GetWorksheet(1);
if (sheet)
{
sheet->Cell(1,1)->SetDouble(1.1);
sheet->Cell(2,2)->SetDouble(2.2);
sheet->Cell(3,3)->SetDouble(3.3);
sheet->Cell(4,4)->SetDouble(4.4);
sheet->Cell(70,2)->SetDouble(5.5);
}
e.SaveAs(example3.xls”);

// Load the newly created sheet and display its contents
e.Load(example3.xls”);

size_t maxSheets = e.GetTotalWorkSheets();
cout << "Total number of worksheets: " << e.GetTotalWorkSheets() << endl;
for (size_t i=0; i<maxSheets; ++i)
{
BasicExcelWorksheet* sheet = e.GetWorksheet(i);
if (sheet)
{
size_t maxRows = sheet->GetTotalRows();
size_t maxCols = sheet->GetTotalCols();
cout << Dimension of " << sheet->GetAnsiSheetName() <<
" (” << maxRows << ", " << maxCols << )” << endl;

  <span class="code-keyword" style="border:0px;color:rgb(0,0,255);">if</span> (maxRows&gt;0)
  {
    printf(<span class="code-string" style="border:0px;color:rgb(128,0,128);">"</span><span class="code-string" style="border:0px;color:rgb(128,0,128);"> "</span>);
    <span class="code-keyword" style="border:0px;color:rgb(0,0,255);">for</span> (<span class="code-sdkkeyword" style="border:0px;color:rgb(51,153,153);">size_t</span> c=<span class="code-digit" style="border:0px;color:rgb(0,0,128);">0</span>; c&lt;maxCols; ++c) printf(<span class="code-string" style="border:0px;color:rgb(128,0,128);">"</span><span class="code-string" style="border:0px;color:rgb(128,0,128);">%10d"</span>, c+1);
    cout &lt;&lt; endl;
  }

  <span class="code-keyword" style="border:0px;color:rgb(0,0,255);">for</span> (<span class="code-sdkkeyword" style="border:0px;color:rgb(51,153,153);">size_t</span> r=<span class="code-digit" style="border:0px;color:rgb(0,0,128);">0</span>; r&lt;maxRows; ++r)
  {
    printf(<span class="code-string" style="border:0px;color:rgb(128,0,128);">"</span><span class="code-string" style="border:0px;color:rgb(128,0,128);">%10d"</span>, r+1);
    <span class="code-keyword" style="border:0px;color:rgb(0,0,255);">for</span> (<span class="code-sdkkeyword" style="border:0px;color:rgb(51,153,153);">size_t</span> c=<span class="code-digit" style="border:0px;color:rgb(0,0,128);">0</span>; c&lt;maxCols; ++c)
    {
      cout &lt;&lt; setw(<span class="code-digit" style="border:0px;color:rgb(0,0,128);">10</span>) &lt;&lt; *(sheet-&gt;Cell(r,c));
    <span class="code-comment" style="border:0px;color:rgb(0,128,0);font-style:italic;">//</span><span class="code-comment" style="border:0px;color:rgb(0,128,0);font-style:italic;"> Another way of printing a cell content.</span>
    }
    cout &lt;&lt; endl;
  }
  <span class="code-keyword" style="border:0px;color:rgb(0,0,255);">if</span> (i==<span class="code-digit" style="border:0px;color:rgb(0,0,128);">0</span>)
  {
    ofstream f(<span class="code-string" style="border:0px;color:rgb(128,0,128);">"</span><span class="code-string" style="border:0px;color:rgb(128,0,128);">example4.csv"</span>);
    sheet-&gt;Print(f, <span class="code-string" style="border:0px;color:rgb(128,0,128);">'</span><span class="code-string" style="border:0px;color:rgb(128,0,128);">,'</span>, <span class="code-string" style="border:0px;color:rgb(128,0,128);">'</span><span class="code-string" style="border:0px;color:rgb(128,0,128);">\"'</span>); <span class="code-comment" style="border:0px;color:rgb(0,128,0);font-style:italic;">//</span><span class="code-comment" style="border:0px;color:rgb(0,128,0);font-style:italic;"> Save the first sheet as a CSV file.</span>
    f.close();
  }
}
cout &lt;&lt; endl;

}
return 0;
}

参考


  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值