【语言-C++】Excel “SYLK (符号链接) *.slk”或剪切板CF_SYLK格式解析

简介

SLK (Symbolic Link, 符号链接,也可简写为"SYLK"),是一种电子表格数据库格式。

如果想了解更多参数信息,参见“SYLK 格式详解1.1.pdf

获取SYLK 格式的途径有很多,常见的有以下两种:

1、用Excel另存为*.slk文件;

2、ClipboardCF_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

统计字体格式索引

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值