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(" ");
    for (size_t c=0; c<maxCols; ++c) printf("%10d", c+1);
    cout << endl;

    for (size_t r=0; r<maxRows; ++r)
    {
      printf("%10d", r+1);
      for (size_t c=0; c<maxCols; ++c)
      {
        BasicExcelCell* cell = sheet1->Cell(r,c);
        switch (cell->Type())
        {
          case BasicExcelCell::UNDEFINED:
            printf(" ");
            break;

          case BasicExcelCell::INT:
            printf("%10d", cell->GetInteger());
            break;

          case BasicExcelCell::DOUBLE:
            printf("%10.6lf", cell->GetDouble());
            break;

          case BasicExcelCell::STRING:
            printf("%10s", cell->GetString());
            break;

          case BasicExcelCell::WSTRING:
            wprintf(L"%10s", cell->GetWString());
            break;
        }
      }
      cout << 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->Cell(1,3);
    cell->SetDouble(3.141592654);

    sheet->Cell(1,4)->SetString("Test str1");
    sheet->Cell(2,0)->SetString("Test str2");
    sheet->Cell(2,5)->SetString("Test str1");

    sheet->Cell(4,0)->SetDouble(1.1);
    sheet->Cell(4,1)->SetDouble(2.2);
    sheet->Cell(4,2)->SetDouble(3.3);
    sheet->Cell(4,3)->SetDouble(4.4);
    sheet->Cell(4,4)->SetDouble(5.5);

    sheet->Cell(4,4)->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;

      if (maxRows>0)
      {
        printf(" ");
        for (size_t c=0; c<maxCols; ++c) printf("%10d", c+1);
        cout << endl;
      }

      for (size_t r=0; r<maxRows; ++r)
      {
        printf("%10d", r+1);
        for (size_t c=0; c<maxCols; ++c)
        {
          cout << setw(10) << *(sheet->Cell(r,c));
        // Another way of printing a cell content.
        }
        cout << endl;
      }
      if (i==0)
      {
        ofstream f("example4.csv");
        sheet->Print(f, ',', '\"'); // Save the first sheet as a CSV file.
        f.close();
      }
    }
    cout << endl;
  }
  return 0;
}

参考


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值