// xlsDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "xls.h"
#include "xlsDlg.h"
#include "afxdialogex.h"
#include "Excel.h"
#include <xstring>
#include <locale.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// 对话框数据
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// CxlsDlg 对话框
CxlsDlg::CxlsDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CxlsDlg::IDD, pParent)
, m_xlsxFileName(_T(""))
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CxlsDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_MFCEDITBROWSE1, m_xlsxFileName);
DDX_Control(pDX, IDC_COMBO1, m_comboItem);
}
BEGIN_MESSAGE_MAP(CxlsDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDOK, &CxlsDlg::OnBnClickedOk)
ON_CBN_DROPDOWN(IDC_COMBO1, &CxlsDlg::OnCbnDropdownCombo1)
ON_BN_CLICKED(IDOK3, &CxlsDlg::OnBnClickedOk3)
END_MESSAGE_MAP()
// CxlsDlg 消息处理程序
BOOL CxlsDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
GetDlgItem(IDC_EDIT3)->SetWindowText(_T("Gain_X,Gain_Y,AFCode,Staic_W_NewAver,Staic_H_NewAver,OFF_W_NewAver,OFF_H_NewAver,ON_W_NewAver,ON_H_NewAver,SR_W_NewAver,SR_H_NewAver,"));
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CxlsDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CxlsDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CxlsDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CxlsDlg::OnBnClickedOk()
{
Parse();
//CDialogEx::OnOK();
}
void CxlsDlg::OnBnClickedOk3()
{
Parse(false);
}
void CxlsDlg::OnCbnDropdownCombo1()
{
m_comboItem.ResetContent();
GetDlgItemText(IDC_MFCEDITBROWSE1, m_xlsxFileName);
if (m_xlsxFileName == _T(""))
{
AfxMessageBox(_T("文件不能为空!"));
return;
}
Excel excel;
bool bInit = excel.initExcel();
//打开excel文件
std::string path = CT2A(m_xlsxFileName);
if (!excel.open(path.c_str()))
{
AfxMessageBox(_T("excel文件打开出错!"));
excel.release();
return;
}
bool bLoad = excel.loadSheet( excel.getSheetName(1));
CString cell;
cell = excel.getCellString(2, 9);
int i = cell.Find(_T(":OK;"));
while (i>-1)
{
CString itemName = cell.Left(i);
int j = itemName.ReverseFind(_T(';'));
if (j>-1)
{
itemName = itemName.Mid(j+1);
m_comboItem.AddString(itemName);
cell = cell.Mid(i+4);
i = cell.Find(_T(":OK;"));
}
}
//清理资源
excel.close();
excel.release();
}
void CxlsDlg::Parse( bool isSFR/*=true*/ )
{
GetDlgItemText(IDC_MFCEDITBROWSE1, m_xlsxFileName);
if (m_xlsxFileName == _T(""))
{
AfxMessageBox(_T("请选择excel文件!"));
return;
}
CString strText;
GetDlgItem(IDC_COMBO1)->GetWindowText(strText);
if (strText == _T(""))
{
AfxMessageBox(_T("请选择需要解析的测试项!"));
return;
}
AfxMessageBox(_T("文件转换中,请耐心等待,不要关闭窗口!"));
Excel excel;
bool bInit = excel.initExcel();
//打开excel文件
std::string path = CT2A(m_xlsxFileName);
if (!excel.open(path.c_str()))
{
AfxMessageBox(_T("excel文件打开出错!"));
}
CString strSheetName = excel.getSheetName(1); //获取第一个sheet名
bool bLoad = excel.loadSheet(strSheetName); //装载sheet
int nRow = excel.getRowCount(); //获取sheet中行数
int nCol = excel.getColumnCount(); //获取sheet中列数
CString cell;
//std::string cells;
CString strHead(_T(""));
CString strContent(_T(""));
for (int i = 1; i <= nRow; ++i)
{
for (int j = 1; j <= nCol ; ++j){
cell = excel.getCellString(i, j); //获取一个单元格数据
//cells = CT2A(cell); //将获取的单元格转换为string类型数据
if (i==1)
{
if (j<9)
{
strHead += (cell + _T(","));
}
}
else
{
if (j<9)
{
strContent += (cell + _T(","));
}
else
{
CString strTempHead(_T(""));
CString strTempContent(_T(""));
parseCell(cell, strTempHead, strTempContent,isSFR);
if (i == 2)
strHead += strTempHead;
strContent += strTempContent;
}
}
}
}
//清理资源
excel.close();
excel.release();
//转换为csv文件
CString csvFileName = _T("Leng20230904.csv");
CFileFind ft;
if(ft.FindFile(csvFileName)) //存在;
{
CFile cfile;
cfile.Remove(csvFileName);
}
CStdioFile csf;
if (!csf.Open(csvFileName, CFile::modeRead|CFile::modeWrite|CFile::modeCreate))
{
AfxMessageBox(_T("csv文件打开出错!"));
}
setlocale(LC_CTYPE, ("chs"));
csf.WriteString(strHead + strContent);
csf.Close();
AfxMessageBox(_T("文件转换完成!"));
}
void CxlsDlg::parseCell( CString cell, CString &strHead, CString &strContent, BOOL isSFR )
{
const std::string SFR_KEY =
"AF_BestCode," \
"OtpCode," \
"SensorTmp," \
"0.00F_0_H," \
"0.00F_0_V," \
"0.30F_36_H," \
"0.30F_36_V," \
"0.30F_144_H," \
"0.30F_144_V," \
"0.30F_216_H," \
"0.30F_216_V," \
"0.30F_324_H," \
"0.30F_324_V," \
"0.50F_36_H," \
"0.50F_36_V," \
"0.50F_144_H," \
"0.50F_144_V," \
"0.50F_216_H," \
"0.50F_216_V," \
"0.50F_324_H," \
"0.50F_324_V," \
"0.70F_36_H," \
"0.70F_36_V," \
"0.70F_144_H," \
"0.70F_144_V," \
"0.70F_216_H," \
"0.70F_216_V," \
"0.70F_324_H," \
"0.70F_324_V," \
"0.80F_36_H," \
"0.80F_36_V," \
"0.80F_144_H," \
"0.80F_144_V," \
"0.80F_216_H," \
"0.80F_216_V," \
"0.80F_324_H," \
"0.80F_324_V," \
"CTC0.80_H," \
"CTC0.80_V,";
std::string strKey = "";
std::string strValue = "";
CString strText;
std::string str = CT2A(cell);
int a, b;
std::string strTemp;
GetDlgItem(IDC_COMBO1)->GetWindowText(strText);
if (strText != _T(""))
{
a = str.find(CT2A(strText) + ":OK;"); //结束字符串
if (a < 0)
{
a = str.find(CT2A(strText) + ":NG;");
}
if (a > 0)
{
strTemp = str.substr(0, a);
b = strTemp.rfind(":OK;"); //起始字符串
int ng = strTemp.rfind(":NG;");
if (ng>b)
b = ng;
if (b<0)
b = 0;
std::string strInf = strTemp.substr(b);
if (!isSFR)
GetDlgItem(IDC_EDIT3)->GetWindowText(strText);
else
strText = SFR_KEY.c_str();
if (strText != _T(""))
{
std::string text = CT2A(strText);
int x = text.find(",");
while (x > -1)
{
std::string tempKey = text.substr(0,x);
if (getValue(strInf,tempKey, strValue))
{
strKey += tempKey;
strKey += ",";
}
text = text.substr(x+1);
x = text.find(",");
}
}
}
}
strKey += ",\n";
strValue += ",\n";
strHead = strKey.c_str();
strContent = strValue.c_str();
}
BOOL CxlsDlg::getValue( std::string str, std::string key, std::string &strValue )
{
int i = str.find(key);
if (i > 0)
{
std::string strTemp1 = str.substr(i + key.length() + 1);
std::string strTemp2 = strTemp1.substr(0, strTemp1.find(";"));
i = strTemp2.find(">");
if (i > 0)
{
strTemp2 = strTemp1.substr(0, strTemp1.find(";") - 1);
}
strTemp2 += ",";
strValue += strTemp2;
return TRUE;
}
return FALSE;
}
//excel.h
#pragma once
#include "CApplication.h"
#include "CRange.h"
#include "CWorkbook.h"
#include "CWorkbooks.h"
#include "CWorksheet.h"
#include "CWorksheets.h"
class Excel
{
private:
CString openFileName;
CWorkbook workBook;//当前处理文件
CWorkbooks books;//ExcelBook集合,多文件时使用
CWorksheet workSheet;//当前使用sheet
CWorksheets sheets;//Excel的sheet集合
CRange currentRange;//当前操作区域
bool isLoad;//是否已经加载了某个sheet数据
COleSafeArray safeArray;
protected:
static CApplication application;//Excel进程实例
public:
Excel();
virtual ~Excel();
void show(bool bShow);
//检查一个cell是否为字符串
bool isCellString(long iRow, long iColumn);
//检查一个cell是否为数值
bool isCellInt(long iRow, long iColumn);
//得到一个cell的string
CString getCellString(long iRow, long iColumn);
//得到一个cell的整数
int getCellInt(long iRow, long iColumn);
//得到一个cell的double数据
double getCellDouble(long iRow, long iColumn);
//取得行的总数
int getRowCount();
//取得列的整数
int getColumnCount();
//使用某个shell
bool loadSheet(long tableId, bool preLoaded = false);
bool loadSheet(CString sheet, bool preLoaded = false);
//通过序号取得某个shell的名称
CString getSheetName(long tableID);
//得到sheel的总数
int getSheetCount();
//打开excel文件
bool open(const char* fileName);
//关闭打开的excel文件
void close(bool ifSave = false);
//另存为一个excel文件
void saveAsXLSFile(const CString &xlsFile);
//取得打开文件的名称
CString getOpenFileName();
//取得打开sheel的名称
CString getOpenSheelName();
//向cell中写入一个int值
void setCellInt(long iRow, long iColumn, int newInt);
//向cell中写入一个字符串
void setCellString(long iRow, long iColumn, CString newString);
public:
//初始化 Excel_OLE
static bool initExcel();
//释放Excel_OLE
static void release();
//取得列的名称
static char* getColumnName(long iColumn);
protected:
void preLoadSheet();
};
//Excel.cpp
#include "stdafx.h"
#include <tchar.h>
#include "Excel.h"
COleVariant
covTrue((short)TRUE),
covFalse((short)FALSE),
covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
CApplication Excel::application;
Excel::Excel() :isLoad(false)
{
}
Excel::~Excel()
{
//close();
}
bool Excel::initExcel()
{
//创建Excel 2000服务器(启动Excel)
if (!application.CreateDispatch(_T("Excel.application"), nullptr))
{
MessageBox(nullptr, _T("创建Excel服务失败,你可能没有安装EXCEL,请检查!"), _T("错误"), MB_OK);
return FALSE;
}
application.put_DisplayAlerts(FALSE);
return true;
}
void Excel::release()
{
application.Quit();
application.ReleaseDispatch();
application = nullptr;
}
bool Excel::open(const char* fileName)
{
//先关闭文件
close();
//利用模板建立新文档
books.AttachDispatch(application.get_Workbooks(), true);
LPDISPATCH lpDis = nullptr;
lpDis = books.Add(COleVariant(CString(fileName)));
if (lpDis)
{
workBook.AttachDispatch(lpDis);
sheets.AttachDispatch(workBook.get_Worksheets());
openFileName = fileName;
return true;
}
return false;
}
void Excel::close(bool ifSave)
{
//如果文件已经打开,关闭文件
if (!openFileName.IsEmpty())
{
//如果保存,交给用户控制,让用户自己存,如果自己SAVE,会出现莫名的等待
if (ifSave)
{
//show(true);
}
else
{
workBook.Close(COleVariant(short(FALSE)), COleVariant(openFileName), covOptional);
books.Close();
}
//清空打开文件名称
openFileName.Empty();
}
sheets.ReleaseDispatch();
workSheet.ReleaseDispatch();
currentRange.ReleaseDispatch();
workBook.ReleaseDispatch();
books.ReleaseDispatch();
}
void Excel::saveAsXLSFile(const CString &xlsFile)
{
workBook.SaveAs(COleVariant(xlsFile),
covOptional,
covOptional,
covOptional,
covOptional,
covOptional,
0,
covOptional,
covOptional,
covOptional,
covOptional,
covOptional);
return;
}
int Excel::getSheetCount()
{
return sheets.get_Count();
}
CString Excel::getSheetName(long tableID)
{
CWorksheet sheet;
sheet.AttachDispatch(sheets.get_Item(COleVariant((long)tableID)));
CString name = sheet.get_Name();
sheet.ReleaseDispatch();
return name;
}
void Excel::preLoadSheet()
{
CRange used_range;
used_range = workSheet.get_UsedRange();
VARIANT ret_ary = used_range.get_Value2();
if (!(ret_ary.vt & VT_ARRAY))
{
return;
}
//
safeArray.Clear();
safeArray.Attach(ret_ary);
}
//按照名称加载sheet表格,也可提前加载所有表格
bool Excel::loadSheet(long tableId, bool preLoaded)
{
LPDISPATCH lpDis = nullptr;
currentRange.ReleaseDispatch();
currentRange.ReleaseDispatch();
lpDis = sheets.get_Item(COleVariant((long)tableId));
if (lpDis)
{
workSheet.AttachDispatch(lpDis, true);
currentRange.AttachDispatch(workSheet.get_Cells(), true);
}
else
{
return false;
}
isLoad = false;
//如果进行预先加载
if (preLoaded)
{
preLoadSheet();
isLoad = true;
}
return true;
}
bool Excel::loadSheet(CString sheet, bool preLoaded)
{
LPDISPATCH lpDis = nullptr;
currentRange.ReleaseDispatch();
currentRange.ReleaseDispatch();
lpDis = sheets.get_Item(COleVariant(sheet));
if (lpDis)
{
workSheet.AttachDispatch(lpDis, true);
currentRange.AttachDispatch(workSheet.get_Cells(), true);
}
else
{
return false;
}
isLoad = false;
//如果进行预先加载
if (preLoaded)
{
preLoadSheet();
isLoad = true;
}
return true;
}
int Excel::getColumnCount()
{
CRange range;
CRange usedRange;
usedRange.AttachDispatch(workSheet.get_UsedRange(), true);
range.AttachDispatch(usedRange.get_Columns(), true);
int count = range.get_Count();
usedRange.ReleaseDispatch();
range.ReleaseDispatch();
return count;
}
int Excel::getRowCount()
{
CRange range;
CRange usedRange;
usedRange.AttachDispatch(workSheet.get_UsedRange(), true);
range.AttachDispatch(usedRange.get_Rows(), true);
int count = range.get_Count();
usedRange.ReleaseDispatch();
range.ReleaseDispatch();
return count;
}
bool Excel::isCellString(long iRow, long iColumn)
{
CRange range;
range.AttachDispatch(currentRange.get_Item(COleVariant((long)iRow), COleVariant((long)iColumn)).pdispVal, true);
COleVariant vResult = range.get_Value2();
//VT_BSTR标示字符串
if (vResult.vt == VT_BSTR)
{
return true;
}
return false;
}
bool Excel::isCellInt(long iRow, long iColumn)
{
CRange range;
range.AttachDispatch(currentRange.get_Item(COleVariant((long)iRow), COleVariant((long)iColumn)).pdispVal, true);
COleVariant vResult = range.get_Value2();
//VT_BSTR标示字符串
if (vResult.vt == VT_INT || vResult.vt == VT_R8)
{
return true;
}
return false;
}
CString Excel::getCellString(long iRow, long iColumn)
{
COleVariant vResult;
CString str;
//字符串
if (isLoad == false)
{
CRange range;
range.AttachDispatch(currentRange.get_Item(COleVariant((long)iRow), COleVariant((long)iColumn)).pdispVal, true);
vResult = range.get_Value2();
range.ReleaseDispatch();
}
//如果数据依据预先加载了
else
{
long read_address[2];
VARIANT val;
read_address[0] = iRow;
read_address[1] = iColumn;
safeArray.GetElement(read_address, &val);
vResult = val;
}
if (vResult.vt == VT_BSTR)
{
str = vResult.bstrVal;
}
//整数
else if (vResult.vt == VT_INT)
{
str.Format(_T("%d"), vResult.pintVal);
}
//8字节的数字
else if (vResult.vt == VT_R8)
{
str.Format(_T("%0.0f"), vResult.dblVal);
}
//时间格式
else if (vResult.vt == VT_DATE)
{
SYSTEMTIME st;
VariantTimeToSystemTime(vResult.date, &st);
CTime tm(st);
str = tm.Format(_T("%Y-%m-%d"));
}
//单元格空的
else if (vResult.vt == VT_EMPTY)
{
str = "";
}
return str;
}
double Excel::getCellDouble(long iRow, long iColumn)
{
double rtn_value = 0;
COleVariant vresult;
//字符串
if (isLoad == false)
{
CRange range;
range.AttachDispatch(currentRange.get_Item(COleVariant((long)iRow), COleVariant((long)iColumn)).pdispVal, true);
vresult = range.get_Value2();
range.ReleaseDispatch();
}
//如果数据依据预先加载了
else
{
long read_address[2];
VARIANT val;
read_address[0] = iRow;
read_address[1] = iColumn;
safeArray.GetElement(read_address, &val);
vresult = val;
}
if (vresult.vt == VT_R8)
{
rtn_value = vresult.dblVal;
}
return rtn_value;
}
int Excel::getCellInt(long iRow, long iColumn)
{
int num;
COleVariant vresult;
if (isLoad == FALSE)
{
CRange range;
range.AttachDispatch(currentRange.get_Item(COleVariant((long)iRow), COleVariant((long)iColumn)).pdispVal, true);
vresult = range.get_Value2();
range.ReleaseDispatch();
}
else
{
long read_address[2];
VARIANT val;
read_address[0] = iRow;
read_address[1] = iColumn;
safeArray.GetElement(read_address, &val);
vresult = val;
}
//
num = static_cast<int>(vresult.dblVal);
return num;
}
void Excel::setCellString(long iRow, long iColumn, CString newString)
{
COleVariant new_value(newString);
CRange start_range = workSheet.get_Range(COleVariant(_T("A1")), covOptional);
CRange write_range = start_range.get_Offset(COleVariant((long)iRow - 1), COleVariant((long)iColumn - 1));
write_range.put_Value2(new_value);
start_range.ReleaseDispatch();
write_range.ReleaseDispatch();
}
void Excel::setCellInt(long iRow, long iColumn, int newInt)
{
COleVariant new_value((long)newInt);
CRange start_range = workSheet.get_Range(COleVariant(_T("A1")), covOptional);
CRange write_range = start_range.get_Offset(COleVariant((long)iRow - 1), COleVariant((long)iColumn - 1));
write_range.put_Value2(new_value);
start_range.ReleaseDispatch();
write_range.ReleaseDispatch();
}
void Excel::show(bool bShow)
{
application.put_Visible(bShow);
application.put_UserControl(bShow);
}
CString Excel::getOpenFileName()
{
return openFileName;
}
CString Excel::getOpenSheelName()
{
return workSheet.get_Name();
}
char* Excel::getColumnName(long iColumn)
{
static char column_name[64];
size_t str_len = 0;
while (iColumn > 0)
{
int num_data = iColumn % 26;
iColumn /= 26;
if (num_data == 0)
{
num_data = 26;
iColumn--;
}
column_name[str_len] = (char)((num_data - 1) + 'A');
str_len++;
}
column_name[str_len] = '\0';
//反转
_strrev(column_name);
return column_name;
}