針對Excel表格檔案操作的程式設計實現 (轉)

amyz發表於2007-11-05
針對Excel表格檔案操作的程式設計實現 (轉)[@more@]

 針對表格操作的實現

編譯:徐景周

:namespace prefix = o ns = "urn:schemas--com::office" />

示例原始碼(?paper_id=770)

簡介

  透過本文及配套示例原始碼你可以更加靈活的控制Excel表格檔案,其中包括建立新Excel檔案、寫入表格資料、讀取表格資料(包括對原建Excel檔案自已手工新增的行、列資料的準確讀取),刪除已有Excel表格,對錶格中指定行、列、單元格進行查詢、插入、替換等操作,同時還可以將生成的Excel檔案轉換為按指定分隔符分隔的其它文字格式的檔案。下面是把此方法用VC6編寫的示例執行效果:

word" />dbottom">

基本思路

  基礎實現方法同上篇文章相同,都是透過ODBC來把Excel表格檔案當成檔案來進行讀、寫等操作,所以在Excel表格檔案中寫入的行頭名必須是唯一的(不要重名,相當於資料庫中的ID值)。本文中對Excel檔案的操作都被封裝進一個類CSpreadSheet中,透過它我們可以非常簡便的實現各種Excel表格資料操作,並且可以對該類進行擴充來滿足自己的需求。

具體實現

一、包含Excel檔案操作類標頭檔案

#include "CSpreadSheet.h"

二、新建Excel檔案,並寫入預設資料

// 新建Excel檔名及路徑,TestSheet為內部表名

  CSpreadSheet SS("c:Test.xls", "TestSheet");

  CStringArray sampleArray, testRow;

 

  SS.BeginTransaction();

 

  // 加入標題

  sampleArray.RemoveAll();

  sampleArray.Add("姓名");

  sampleArray.Add("年齡");

  SS.AddHeaders(sampleArray);

 

  // 加入資料

  CString strName[] = {"徐景周","徐志慧","郭徽","牛英俊","朱小鵬"};

  CString strAge[]  = {"27","23","28","27","26"};

  for(int i = 0; i < sizeof(strName)/sizeof(CString); i++)

  {

  sampleArray.RemoveAll();

  sampleArray.Add(strName[i]);

  sampleArray.Add(strAge[i]);

  SS.AddRow(sampleArray);

  }

 

  SS.Commit();

三、讀取Excel檔案資料

CSpreadSheet SS("c:Test.xls", "TestSheet");

  CStringArray Rows, Column;

  //清空列表框

  m_Acceist.ResetContent();

  for (int i = 1; i <= SS.GetTotalRows(); i++)

  {

  // 讀取一行

  SS.ReadRow(Rows, i);

  CString strContents = "";

  for (int j = 1; j <= Rows.GetSize(); j++)

  {

  if(j == 1)

  strContents = Rows.GetAt(j-1);

  else

  strContents = strContents +  " --&gt " + Rows.GetAt(j-1);

  }

  m_AccessList.AddString(strContents);

  }

四、對已存在Excel表格資料進行新增、插入、替換操作

// 初始化測試行資料,進行新增、插入及替換資料操作演示

  for (int k = 1; k <= 2; k++)

  {

  testRow.Add("Test");

  }

 

  SS.AddRow(testRow);  // 新增到尾部

  SS.AddRow(testRow, 2);  // 插入新行到第二行

  SS.AddRow(testRow, 6, true);  // 替換原第四行來新的內容

  SS.AddCell(“徐景周”, 1,2);  // 新增(不存在)或替換(存在)第二行,第一列單元格內容

  SS.Commit();

 

五、對已存在Excel表格資料進行行、列、單元格查詢

void CExcelAccessDlg::OnQuery()

{

  CSpreadSheet SS("c:Test.xls", "TestSheet");

  CStringArray Rows, Column;

  CString tempString = "";

  UpdateData();

  if(m_strRow == "" && m_strColumn == "")  // 查詢為空

  {

  AfxMessageBox("行號、列號不能同時為空!");

  return;

  } 

  else if(m_strRow == "" && m_strColumn != "")  // 查詢指定列資料

  {

  int iColumn = atoi(m_strColumn);

  int iCols = SS.GetTotalColumns();

  if(iColumn > iCols)  // 超出表範圍查詢時

  {

  CString str;

  str.Format("表中總列數為: %d, ", iCols);

  AfxMessageBox(str + " 查詢列數大於Excel表中總列數,請重新輸入!");

  return;

  }

  // 讀取一列資料,並按行讀出

  if(!SS.ReadColumn(Column, iColumn))

  {

  AfxMessageBox(SS.GetLastError());

  return;

  }

  CString tmpStr;

  for (int i = 0; i < Column.GetSize(); i++)

  {

  tmpStr.Format("行號: %d, 列號: %d ,內容: %sn", i+1,iColumn,Column.GetAt(i));

  tempString += tmpStr;

  }

 

  AfxMessageBox(tempString);

  }

  else if(m_strRow != "" && m_strColumn == "")  // 查詢指定行數資料

  {

  int iRow = atoi(m_strRow);

  int iRows = SS.GetTotalRows();

 

  if(iRow > iRows)  // 超出表範圍查詢時

  {

  CString str;

  str.Format("表中總行數為: %d, ", iRows);

  AfxMessageBox(str + " 查詢行數大於Excel表中總行數,請重新輸入!");

  return;

  }

  // 讀取指定行資料

  if(!SS.ReadRow(Rows, iRow))

  {

  AfxMessageBox(SS.GetLastError());

  return;

  }

  CString tmpStr;

  for (int i = 0; i < Rows.GetSize(); i++)

  {

  tmpStr.Format("行號: %d, 列號: %d ,內容: %sn", iRow, i+1, Rows.GetAt(i));

  tempString += tmpStr;

  }

  AfxMessageBox(tempString);

  }

  else if(m_strRow != "" && m_strColumn != "")  // 查詢指定單元格資料

  {

  int iRow = atoi(m_strRow), iColumn = atoi(m_strColumn);

  int iRows = SS.GetTotalRows(), iCols = SS.GetTotalColumns();

 

  if(iColumn > iCols)  // 超出表範圍查詢時

  {

  CString str;

  str.Format("表中總列數為: %d, ", iCols);

  AfxMessageBox(str + " 查詢列數大於Excel表中總列數,請重新輸入!");

  return;

  }

  else if(iRow > iRows)

  {

  CString str;

  str.Format("表中總行數為: %d, ", iRows);

  AfxMessageBox(str + " 查詢行數大於Excel表中總行數,請重新輸入!");

  return;

  }

  // 讀取指定行、列單元格資料

  if(!SS.ReadCell(tempString, iColumn, iRow))

  {

  AfxMessageBox(SS.GetLastError());

  return;

  }

  CString str;

  str.Format("行號: %d, 列號: %d ,內容: %s", iRow,iColumn,tempString);

  AfxMessageBox(str);

  }

 

}

六、將存在的Excel轉換另存為指定分隔的文字檔案

SS.Convert(";");  // 將原Excel檔案轉換為用分號分隔的文字,並另存為同名文字檔案

七、刪除Excel中表格

SS. DeleteSheet();  // 刪除Excel檔案中所有表格

SS. DeleteSheet(" TestSheet ");  // 刪除Excel中TextSheet表格

八、獲取Excel中總行數、總列數、當前行

int iCols = SS.GetTotalColumns();  // 總列數

int iRows = SS.GetTotalRows();  // 總行數

int iCurRow = SS.GetCurrentRow(); // 當前所在行號

九、獲取行頭資料

CStringArray rowHeader;

SS.GetFieldNames(rowHeader);

CString tmpStr;

  for (int i = 0; i < rowHeader.GetSize(); i++)

  {

  tmpStr.Format("行號: %d, 列號: %d ,內容: %sn", 1, i+1, rowHeader.GetAt(i));

  tempString += tmpStr;

  }

  AfxMessageBox(tempString);

最後,如果想知道詳細實現細節的話,可以在下載示例原始碼後,仔細檢視原始碼既可(內有詳細註釋)。

參考文獻:

直接透過ODBC讀、寫Excel表格檔案 – 徐景周(譯)

A Class to Read and Write to Excel and Text Delimited Spreadsheet – Yap Chun Wei

聯絡方式:

地址:陝西省西安市勞動路2號院六單元

郵編:710082

E:

未來工作室(Future Studio)

 

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-980880/,如需轉載,請註明出處,否則將追究法律責任。

相關文章