我有一個程序,通過逐行讀取每個單元格中的每個單元格,將excel轉換爲數據。相當棘手的代碼嗅到解決(由於兩個單獨的庫)C++
要做到這一點,我已經使用了兩個獨立的庫:
我有一個抽象類的算法,以及兩個派生類爲每個。我遇到的問題是,ExcelFormat和Xlsx I/O不遵循相同的格式(因爲它們是單獨的庫,並且不符合相同的基類)。
(注意,我寫了xlsxio的包裝,因爲它是程序性的,並且我想OO功能)
我想抽象算法儘可能給基類。現在我所能做的就是擁有通用的抽象方法Convert(),這非常糟糕,因爲這兩個函數算法非常相似,但無法符合統一界面只是因爲他們不共享相同的基礎。
這是我有:
bool XlsxToData::Convert(const std::string & filePath, std::list<SqlParam*>* params) {
FreeXlsx::XlsxBook book(filePath);
if (book.IsOpen()) {
std::vector<std::string>* sheets = book.GetSheetList();
if (sheets != nullptr) {
std::list<SqlParam*> foundParams;
for (auto itr : *sheets) {
FreeXlsx::XlsxSheet sheet(itr, book);
std::map<int, SqlParam*> foundX;
int longestWidth = 0;
int lastWidth = 0;
if (sheet.IsOpen()) {
sheet.ForSheet([this, &foundParams, &foundX, &longestWidth, &lastWidth, params](const std::string & value, const int & x, const int & y) {
if (x > longestWidth)
longestWidth = x;
lastWidth = x;
GetValueCell(foundX, value, x);
CheckParams(foundX, foundParams, value, x, params);
},
[&longestWidth, &lastWidth, &foundX, this](const int & row) {
if (lastWidth < longestWidth)
for (int i = lastWidth + 1; i <= longestWidth; ++i) {
auto find = foundX.find(i);
if (find != foundX.end()) {
find->second->PushValue("");
}
}
});
sheet.Close();
}
if (params->size() < 1)
break;
}
delete sheets;
while (foundParams.size() > 0) {
params->push_back(*foundParams.begin());
foundParams.erase(foundParams.begin());
}
}
book.Close();
return true;
}
return false;
}
bool XlsToData::Convert(const std::string & filePath, std::list<SqlParam*>* params) {
ExcelFormat::BasicExcel book;
if (book.Load(filePath.c_str())) {
int sheets = book.GetTotalWorkSheets();
std::list<SqlParam*> foundParams;
for (int i = 0; i < sheets; ++i) {
ExcelFormat::BasicExcelWorksheet* sheet = book.GetWorksheet(i);
std::map<int, SqlParam*> foundX;
if (sheet != nullptr) {
const int rows = sheet->GetTotalRows();
const int cols = sheet->GetTotalCols();
std::map<int, SqlParam*> foundX;
for (int row = 0; row < rows; ++row) {
bool willBreak = false;
for (int col = 0; col < cols; ++col) {
ExcelFormat::BasicExcelCell * cell = sheet->Cell(row, col);
if (cell != nullptr) {
std::string value = getval(cell);
GetValueCell(foundX, value, col);
CheckParams(foundX, foundParams, value, col, params);
}
}
if (willBreak)
break;
}
}
}
while (foundParams.size() > 0) {
params->push_back(*foundParams.begin());
foundParams.erase(foundParams.begin());
}
book.Close();
return true;
}
return false;
}
我希望能夠抽象方法來打開書籍/張成單一的方法爲遍歷每個單元格的過程。
我已經考慮過可能修改ExcelFormat的源碼和Xlsx I/o的Wrapper類以使用統一的抽象基礎。
請問這是最明智的方式嗎?
這種衝突有沒有設計模式?
我應該實現一個從Excel格式的類繼承的適配器類,然後有Xlsxio包裝和新的適配器類符合新的抽象基地?
或者沒有人有更好的解決方案嗎?
感謝。
編輯:另外,側面說明,我意識到這顯然有很長的方法代碼氣味。我打算用更廣義的算法來重構這個。