简介
SLK (Symbolic Link, 符号链接,也可简写为"SYLK"),是一种电子表格数据库格式。
如果想了解更多参数信息,参见“SYLK 格式详解1.1.pdf”
获取SYLK 格式的途径有很多,常见的有以下两种:
1、用Excel另存为*.slk文件;
2、Clipboard中CF_SYLE类型的数据(打开Excel复制一些表格即可得到该类型数据)。
剪贴板解析CF_SYLE代码
获取CF_SYLE数据
HGLOBAL hMem;
if(hMem = ::GetClipboardData(CF_SYLK))
{
char* lpszText = (char* )::GlobalLock(hMem);
CString strText(lpszText);
Process_SKLY(strText);
}
::GlobalUnlock(hMem);
解析部分数据
void CClipboardDlg::Process_SKLY( CString sStr )
{
CString strTmp = sStr;
vector<CString> vecStr;
vector<CString> vecsubStr;
m_SKLY_KPPID = 0;
m_SKLY_KPFID = 0;
int index = 0;
while (index >=0)
{
index=strTmp.Find(_T("\r\n")); //查找第一个","的位置
CString tmp =strTmp.Left(index);
if(tmp.GetLength()>0)
vecStr.push_back(tmp);
int len=strTmp.Delete(0,index); //找出","右边的字符串位数
strTmp = strTmp.Right(len-1);
}
int nPIndex = -1;
for(int k = 0 ; k <vecStr.size() ;k++)
{
CString strSubTmp = vecStr[k];
vecsubStr.clear();
int subIndex = 0;
while (subIndex>=0)
{
subIndex=strSubTmp.Find(_T(";")); //查找第一个","的位置
CString tmpSub =strSubTmp.Left(subIndex);
if(tmpSub.GetLength()>0)
vecsubStr.push_back(tmpSub);
elseif(strSubTmp.GetLength()>0)
vecsubStr.push_back(strSubTmp);
int sublen=strSubTmp.Delete(0,subIndex); //找出","右边的字符串位数
strSubTmp = strSubTmp.Right(sublen-1);
}
if (vecsubStr.size() <= 0)
return;
for(int i = 0 ; i < vecsubStr.size();i++)
RemoveUnuseChar(vecsubStr[i]);
CString stropt;
Process_SKLY_KEY_ID(vecsubStr);
Process_SKLY_KEY_P(vecsubStr);
Process_SKLY_KEY_B(vecsubStr);
Process_SKLY_KEY_C(vecsubStr);
Process_SKLY_KEY_F(vecsubStr);
if (vecsubStr[0].MakeUpper() == _T("E"))
OutputDebugString(_T("结束\n"));
}
}
解析头
bool CClipboardDlg::Process_SKLY_KEY_ID( vector<CString> vecsubStr )
{
if (vecsubStr[0].MakeUpper() != _T("ID"))
return false;
bool bN_exists = false;
bool bE_exists = false;
for(int i = 0 ; i < vecsubStr.size();i++)
{
if (vecsubStr[i].MakeUpper() == _T("N"))
{
bN_exists = true;
}
else if (vecsubStr[i].MakeUpper() == _T("E"))
{
bE_exists = true;
}
else if (vecsubStr[i].MakeUpper() == _T("PWXL"))
{
OutputDebugString(_T("使用软件:Excel\n"));
}
else if (vecsubStr[i].MakeUpper() == _T("PWMP"))
{
OutputDebugString(_T("使用软件:Multiplan\n"));
}
else if (vecsubStr[i].MakeUpper() == _T("P"))
{
OutputDebugString(_T("使用软件:无\n"));
}
}
if (bN_exists )
OutputDebugString(_T("单元保护标识:;N\n"));
else
OutputDebugString(_T("单元保护标识:;P\n"));
if (bE_exists )
OutputDebugString(_T("NE记录是多余\n"));
else
OutputDebugString(_T("NE记录不是多余的\n"));
return true;
}
解析单元与字体格式清单
bool CClipboardDlg::Process_SKLY_KEY_P( vector<CString> vecsubStr )
{
if (vecsubStr[0].MakeUpper() != _T("P"))
return false;
if (vecsubStr.size() <= 1)
{
OutputDebugString(vecsubStr[0]);
}
CString strSubPFormat =vecsubStr[1];
CString stropt ;
CString odsmsg ;
if (strSubPFormat.GetAt(0) == _T('P'))
{
int nSize = vecsubStr.size();
stropt.Format(_T("单元格式清单No.%d:"),m_SKLY_KPPID);
odsmsg = stropt;
m_SKLY_KPPID ++;
for(int i = 1 ; i < vecsubStr.size();i++)
{
if( i == 1)
strSubPFormat = vecsubStr[i].Right(vecsubStr[i].GetLength()-1);
else
strSubPFormat = vecsubStr[i];
if (strSubPFormat.MakeUpper() == _T("GENERAL"))
{
odsmsg += _T("通用格式");
}
else
{
if(i==1)
{
stropt.Format(_T("正数【%s】;"),vecsubStr[i]);
odsmsg += stropt;
}
elseif (i==2)
{
stropt.Format(_T("负数【%s】;"),vecsubStr[i]);
odsmsg += stropt;
}
elseif (i==3)
{
stropt.Format(_T("零【%s】;"),vecsubStr[i]);
odsmsg += stropt;
}
elseif (i==4)
{
stropt.Format(_T("文本【%s】;"),vecsubStr[i]);
odsmsg += stropt;
}
}
if (nSize == i+1)
{
odsmsg += _T("\n");
OutputDebugString(odsmsg);
}
}
}
else if (strSubPFormat.GetAt(0) == _T('E')|| strSubPFormat.GetAt(0) == _T('F'))
{
if (m_SKLY_KPFID ==4)
m_SKLY_KPFID ++;
if (strSubPFormat.GetAt(0) == _T('E'))
{
int nSize = vecsubStr.size();
stropt.Format(_T("字体格式清单-E No.%d:"),m_SKLY_KPFID);
odsmsg = stropt;
m_SKLY_KPFID++;
}
else if (strSubPFormat.GetAt(0) == _T('F'))
{
int nSize = vecsubStr.size();
stropt.Format(_T("字体格式清单-F No.%d:"),m_SKLY_KPFID);
odsmsg = stropt;
m_SKLY_KPFID ++;
}
for(int i = 1 ; i < vecsubStr.size();i++)
{
CString strValue;
CString strName;
CString strSubPFormat= vecsubStr[i];
if (vecsubStr[i].GetAt(0) == _T('E')|| vecsubStr[i].GetAt(0) == _T('F'))
strName = _T("字体");
elseif (vecsubStr[i].GetAt(0) == _T('L'))
strName = _T("颜色");
elseif (vecsubStr[i].GetAt(0) == _T('M'))
strName = _T("字号");
elseif (vecsubStr[i].GetAt(0) == _T('S'))
strName = _T("风格");
else
strName = vecsubStr[i].GetAt(0);
strValue = vecsubStr[i].Right(vecsubStr[i].GetLength()-1);
stropt.Format(_T("%s【%s】;"),strName,strValue);
odsmsg+=stropt;
if (vecsubStr.size() == i+1)
{
odsmsg += _T("\n");
OutputDebugString(odsmsg);
}
}
}
return true;
}
解析边界
bool CClipboardDlg::Process_SKLY_KEY_B( vector<CString> vecsubStr )
{
if (vecsubStr[0].MakeUpper() != _T("B"))
return false;
CString strValue;
CString strName;
CString strParam;
CString stropt;
CString odsmsg;
odsmsg =_T("获取表格边界:");
for(int i = 1 ; i < vecsubStr.size();i++)
{
if (vecsubStr[i].GetAt(0) == _T('D'))
{
vector<CString> vstringW;
vstringW.clear();
strParam = vecsubStr[i].Right(vecsubStr[i].GetLength()-1);
int paramIndex = 0;
while(paramIndex>=0)
{
paramIndex=strParam.Find(_T("")); //查找第一个","的位置
CString tmpSub =strParam.Left(paramIndex);
if(tmpSub.GetLength()>0)
vstringW.push_back(tmpSub);
elseif(strParam.GetLength()>0)
vstringW.push_back(strParam);
intsublen=strParam.Delete(0,paramIndex); //找出","右边的字符串位数
strParam = strParam.Right(sublen-1);
}
if (vstringW.size() >=4)
{
stropt.Format(_T("有效区域(第%d行,第%d列)-(第%d行,第%d列);"),_ttoi(vstringW[0])+1,_ttoi(vstringW[1])+1,_ttoi(vstringW[2])+1,_ttoi(vstringW[3])+1);
odsmsg+=stropt;
}
}
else if (vecsubStr[i].GetAt(0) == _T('Y'))
{
strParam = vecsubStr[i].Right(vecsubStr[i].GetLength()-1);
stropt.Format(_T("行最大值【%s】;"),strParam);
odsmsg+=stropt;
}
else if (vecsubStr[i].GetAt(0) == _T('X'))
{
strParam = vecsubStr[i].Right(vecsubStr[i].GetLength()-1);
stropt.Format(_T("列最大值【%s】;"),strParam);
odsmsg+=stropt;
}
//strValue =vecsubStr[i].Right(vecsubStr[i].GetLength()-1);
//stropt.Format(_T("%s【%s】;"),strName,strValue);
//odsmsg +=stropt;
if (vecsubStr.size() == i+1)
{
odsmsg += _T("\n");
OutputDebugString(odsmsg);
}
}
return true;
}
解析内容与公式
bool CClipboardDlg::Process_SKLY_KEY_C( vector<CString> vecsubStr )
{
if (vecsubStr[0].MakeUpper() != _T("C"))
return false;
CString strParam;
CString stropt;
CString odsmsg;
odsmsg = _T("设置内容与公式-C:");
for(int i = 1 ; i < vecsubStr.size();i++)
{
CString strValue;
CString strName;
if (vecsubStr[i].GetAt(0) == _T('K'))
{
strName = _T("内容");
}
else if (vecsubStr[i].GetAt(0) == _T('E'))
{
strName = _T("公式");
}
else if (vecsubStr[i].GetAt(0) == _T('Y'))
{
strName = _T("行");
}
else if (vecsubStr[i].GetAt(0) == _T('X'))
{
strName = _T("列");
}
strValue = vecsubStr[i].Right(vecsubStr[i].GetLength()-1);
stropt.Format(_T("%s【%s】;"),strName,strValue);
odsmsg += stropt;
if (vecsubStr.size() == i+1)
{
odsmsg += _T("\n");
OutputDebugString(odsmsg);
}
}
return true;
}
解析设置单元格式
bool CClipboardDlg::Process_SKLY_KEY_F( vector<CString> vecsubStr )
{
if (vecsubStr[0].MakeUpper() != _T("F"))
return false;
CString strParam;
CString stropt;
CString odsmsg;
odsmsg = _T("设置单元格式:");
for(int i = 1 ; i < vecsubStr.size();i++)
{
if (vecsubStr[i].GetAt(0) == _T('W'))
{
vector<CString> vstringW;
vstringW.clear();
strParam = vecsubStr[i].Right(vecsubStr[i].GetLength()-1);
int paramIndex = 0;
while(paramIndex>=0)
{
paramIndex=strParam.Find(_T("")); //查找第一个","的位置
CString tmpSub =strParam.Left(paramIndex);
if(tmpSub.GetLength()>0)
vstringW.push_back(tmpSub);
elseif(strParam.GetLength()>0)
vstringW.push_back(strParam);
intsublen=strParam.Delete(0,paramIndex); //找出","右边的字符串位数
strParam = strParam.Right(sublen-1);
}
if (vstringW.size() >=3)
{
stropt.Format(_T("设置第%s列到第%s列的宽度为%s个字符;"),vstringW[0],vstringW[1],vstringW[2]);
odsmsg+=stropt;
}
}
else if (vecsubStr[i].GetAt(0) == _T('P'))
{
strParam = vecsubStr[i].Right(vecsubStr[i].GetLength()-1);
stropt.Format(_T("引用单元格式No.%s;"),strParam);
odsmsg+=stropt;
}
else if (vecsubStr[i].GetAt(0) == _T('M'))
{
strParam = vecsubStr[i].Right(vecsubStr[i].GetLength()-1);
stropt.Format(_T("字号【%f】;"),_ttof(strParam)/20.0);
odsmsg+=stropt;
}
else if (vecsubStr[i].GetAt(0) == _T('S')&&vecsubStr[i].GetAt(0) == _T('M'))
{
strParam = vecsubStr[i].Right(vecsubStr[i].GetLength()-1);
stropt.Format(_T("引用字体格式No.%s;"),strParam);
odsmsg+=stropt;
}
else if (vecsubStr[i].GetAt(0) == _T('Y'))
{
strParam = vecsubStr[i].Right(vecsubStr[i].GetLength()-1);
stropt.Format(_T("第%s行;"),strParam);
odsmsg+=stropt;
}
else if (vecsubStr[i].GetAt(0) == _T('X'))
{
strParam = vecsubStr[i].Right(vecsubStr[i].GetLength()-1);
stropt.Format(_T("第%s列;"),strParam);
odsmsg+=stropt;
}
else if (vecsubStr[i].GetAt(0) == _T('D'))
{
strParam = vecsubStr[i].Right(vecsubStr[i].GetLength()-1);
int Length = strParam.GetLength();
CString nStyle;
CString nDigital;
CString nAlignment;
CString nWidth;
int nV = 1;
for(int j = 0 ;j< Length;j++ )
{
if(
strParam.GetAt(j) == _T('A')|| strParam.GetAt(j) == _T('B') || strParam.GetAt(j) == _T('C') ||
strParam.GetAt(j) == _T('D')|| strParam.GetAt(j) == _T('E') || strParam.GetAt(j) == _T('F') ||
strParam.GetAt(j) == _T('G')|| strParam.GetAt(j) == _T('H') || strParam.GetAt(j) == _T('I') ||
strParam.GetAt(j) == _T('J')|| strParam.GetAt(j) == _T('K') || strParam.GetAt(j) == _T('L') ||
strParam.GetAt(j) == _T('M')|| strParam.GetAt(j) == _T('N') || strParam.GetAt(j) == _T('O') ||
strParam.GetAt(j) == _T('P')|| strParam.GetAt(j) == _T('Q') || strParam.GetAt(j) == _T('R') ||
strParam.GetAt(j) == _T('S')|| strParam.GetAt(j) == _T('T') || strParam.GetAt(j) == _T('U') ||
strParam.GetAt(j) == _T('V')|| strParam.GetAt(j) == _T('W') || strParam.GetAt(j) == _T('X') ||
strParam.GetAt(j) == _T('Y')|| strParam.GetAt(j) == _T('Z')
)
{
if(nV == 1)
{
nStyle = strParam.GetAt(j);
}
elseif (nV == 2)
{
nAlignment = strParam.GetAt(j);
}
nV++;
}
if(
strParam.GetAt(j) == _T('0')|| strParam.GetAt(j) == _T('1') || strParam.GetAt(j) == _T('2') ||
strParam.GetAt(j) == _T('3')|| strParam.GetAt(j) == _T('4') || strParam.GetAt(j) == _T('5') ||
strParam.GetAt(j) == _T('6')|| strParam.GetAt(j) == _T('7') || strParam.GetAt(j) == _T('8') ||
strParam.GetAt(j) == _T('9')
)
{
if(nV == 2)
{
nDigital += strParam.GetAt(j);
}
elseif (nV == 3)
{
nWidth += strParam.GetAt(j);
}
}
}
stropt.Format(_T("数值格式【%s】-保留小数点【%s】-对齐方式【%s】-显示字符数【%s】;"),nStyle,nDigital,nAlignment,nWidth);
odsmsg+=stropt;
}
if (vecsubStr.size() == i+1)
{
odsmsg += _T("\n");
OutputDebugString(odsmsg);
}
}
return true;
}
解析选项
bool CClipboardDlg::Process_SKLY_KEY_O( vector<CString> vecsubStr )
{
if (vecsubStr[0].MakeUpper() != _T("O"))
return false;
OutputDebugString(_T("设置选项\n"));
for(int i = 1 ; i < vecsubStr.size();i++)
{
OutputDebugString(vecsubStr[i]);
}
return true;
}
辅助函数
删除无用数据
CString RemoveUnuseChar(CString &str)
{
int nIndex = 0;
CString tmp;
str.Remove(_T('\r'));
str.Remove(_T('\n'));
str.Remove(_T(';'));
str.Remove(_T('\t'));
return str;
}
辅助参数
参数 | 含义 |
m_SKLY_KPPID | 统计单元格式索引 |
m_SKLY_KPFID | 统计字体格式索引 |