#include "stdafx.h" #include "ExcelWrite.h" #include "excel9.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif CExcelWrite::CExcelWrite() { } CExcelWrite::~CExcelWrite() { } BOOL CExcelWrite::ExcelWrite(CListCtrl* pListCtrl, LPCTSTR pszIniDefFile, BOOL bOpen) { if (NULL == pListCtrl || NULL == pszIniDefFile) return FALSE; //1.读取xls文件定义名 CString sReportFile = pszIniDefFile; sReportFile.MakeLower(); sReportFile.Replace(_T(".ini"),_T(".xls")); /*::GetPrivateProfileString(_T("File"), _T("Templ"), _T(""), sReportFile.GetBuffer(MAX_PATH), MAX_PATH, pszIniDefFile); sReportFile.ReleaseBuffer(); sReportFile.Replace(_T('/'), _T('\\')); // 确定xls文件名 if (sReportFile.IsEmpty()) { LPCTSTR pszSub = _tcsrchr(pszIniDefFile, _T('\\')) + 1; sReportFile = pszSub; int iFind = sReportFile.ReverseFind(_T('.')); if (iFind > 0) sReportFile.Delete(iFind, 4); sReportFile += _T(".xls"); } // 确定xls文件位置 if (sReportFile.ReverseFind(_T('\\')) < 0) { TCHAR szPathName[MAX_PATH]; ::GetModuleFileName(NULL, szPathName, MAX_PATH); LPTSTR pszSub = _tcsrchr(szPathName, _T('\\')); ASSERT(NULL != pszSub); pszSub[1] = _T('\0'); _tcscat(szPathName, _T("Report\\")); sReportFile.Insert(0, szPathName); }*/ //2.行定义 int nRowFrom = ::GetPrivateProfileInt(_T("Row"),_T("RowFrom"),-1,pszIniDefFile); int nRowTo = ::GetPrivateProfileInt(_T("Row"),_T("RowTo"),-1,pszIniDefFile); if (nRowFrom == -1 ) { AfxMessageBox(_T("配置文件的定义信息不完整!请检查配置文件!")); return FALSE; } TCHAR szResult[_MAX_PATH]; ::GetPrivateProfileString(_T("Row"),_T("Cells"),_T("Null"),szResult,_MAX_PATH,pszIniDefFile); if (_tcscmp(szResult,_T("Null")) == 0) { AfxMessageBox(_T("配置文件的定义信息不完整!请检查配置文件!")); return FALSE; } CStringArray arCells; ScriptToCells(szResult,arCells); //3. 依次读取cell对应的listCtrl名称 CMapStringToString mapCellToCols; CString sCell,sCellScr; for (int i = 0;i < arCells.GetSize();i++) { sCell = arCells.GetAt(i); ::GetPrivateProfileString(_T("Cell"),sCell,_T("Null"),szResult,_MAX_PATH,pszIniDefFile); if (_tcscmp(szResult,_T("Null")) != 0) { //一个单元格可能和多个列脚本有关 sCellScr = szResult; sCellScr.TrimLeft(); sCellScr.TrimRight(); mapCellToCols.SetAt(sCell,sCellScr); } } //4. 开始写文件 return ImpWriteExcel(nRowFrom,nRowTo,sReportFile,mapCellToCols,pListCtrl,bOpen); } BOOL CExcelWrite::ImpWriteExcel(int nRowFrom,int nRowTo,CString& sXlsTmplFile, CMapStringToString& mapCellToCols,CListCtrl* pListCtrl,BOOL bOpen) { ASSERT(pListCtrl != NULL); ::CoInitialize(NULL); _Application excelApp; Workbooks excelBooks; _Workbook excelBook; Worksheets excelSheets; _Worksheet excelSheet; COleVariant vResult; COleVariant covTrue((short)TRUE),covFalse((short)FALSE); COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR); Range range; Range iCell; BOOL bSuccess = excelApp.CreateDispatch(_T("excel.application")); if (bSuccess) { LPDISPATCH pLpDisp = NULL; excelBooks.AttachDispatch(excelApp.GetWorkbooks()); pLpDisp = excelBooks.Open( sXlsTmplFile,covOptional,covOptional,covOptional, covOptional,covOptional,covOptional,covOptional, covOptional,covOptional,covOptional,covOptional, covOptional); if (pLpDisp == NULL) { AfxMessageBox(_T("启动excel 服务失败!请确认系统是否安装Excel!")); return FALSE; } excelBook.AttachDispatch(pLpDisp); //得到Worksheets excelSheets.AttachDispatch(excelBook.GetWorksheets()); //获取sheet 数量 long lCount = excelSheets.GetCount(); //从第一模板sheet开始 short nSheetIndex = 1; COleVariant varIndex(nSheetIndex); pLpDisp = excelSheets.GetItem(varIndex); if (pLpDisp != NULL) { excelSheet.AttachDispatch(pLpDisp); CString sCellIndex,sCols,sValue,sCell; //遍历所有的明细行数据 int nRowIndex = 0; for (int i = 0;i < pListCtrl->GetItemCount();i++) { for (POSITION ps = mapCellToCols.GetStartPosition();ps != NULL;) { mapCellToCols.GetNextAssoc(ps,sCellIndex,sCols); //根据Cols 合成该行数据文本 sValue = _T(""); FormatColsValue(pListCtrl,i,sCols,sValue); sCell.Format(_T("%s%d"),sCellIndex,nRowFrom + nRowIndex); COleVariant varCell(sCell); range = excelSheet.GetRange(varCell,varCell); COleVariant varText(sValue); range.SetValue(varText); } nRowIndex += 1; if (nRowTo != -1 && nRowTo > nRowFrom)//有要求分页的情况 { if ((nRowFrom + nRowIndex) > nRowTo) { nSheetIndex = (nRowFrom + i) / (nRowTo - nRowFrom) + ( (nRowFrom + i) % (nRowTo - nRowFrom) ? 1 : 0); if (varIndex.iVal != nSheetIndex) { if (nSheetIndex >= lCount) { AfxMessageBox(_T("模板文件Sheet数量不够,明细部分数据没有导出,请增加模板Sheet后再导出!")); break; } varIndex.iVal = nSheetIndex; pLpDisp = excelSheets.GetItem(varIndex); if (pLpDisp != NULL) { nRowIndex = 0; excelSheet.AttachDispatch(pLpDisp); } else { AfxMessageBox(_T("获取第%d模板Sheet失败,明细部分数据没有导出,请检查模板Excel文件!")); break; } } } } } } //年月 日 分 秒 文件记录 CString sAdd; CString sSaveAsFileName = sXlsTmplFile; CTime tNow = CTime::GetCurrentTime(); sAdd = tNow.Format(" %Y-%m-%d %H.%M.%S"); sAdd += _T(".xls"); sSaveAsFileName.Replace(_T(".xls"),sAdd); //另外保存新文件 COleVariant varNewEFile(sSaveAsFileName); excelBook.SaveAs(varNewEFile,covOptional,covOptional,covOptional, covOptional,covOptional,0,covOptional,covOptional, covOptional,covOptional); excelBooks.Close(); excelApp.Quit(); if (bOpen) { ShellExecute(AfxGetMainWnd()->m_hWnd,_T("open"),sSaveAsFileName,_T(""),_T(""),SW_SHOWNORMAL); } } else { ::CoUninitialize(); AfxMessageBox(_T("创建xls失败! 报表到xls文件需要本机安装Microsoft excel 软件!")); return FALSE; } ::CoUninitialize(); return TRUE; } BOOL CExcelWrite::FormatColsValue(CListCtrl* pListCtrl,int nItem,CString& sCols,CString& sValue) { sValue = sCols; HDITEM hdi; TCHAR lpBuffer[_MAX_PATH]; memset(lpBuffer,0,_MAX_PATH); hdi.mask = HDI_TEXT; hdi.pszText = lpBuffer; hdi.cchTextMax = _MAX_PATH; CString sText,sTextAll = _T(""),sValueBk = sValue; int nCount = pListCtrl->GetHeaderCtrl()->GetItemCount(); for (int i = 0;i < nCount;i++) { pListCtrl->GetHeaderCtrl()->GetItem(i,&hdi); //找到listctrl的列名称 if (sCols.Find(hdi.pszText,0) != -1) { sText = pListCtrl->GetItemText(nItem,i); sTextAll += sText; sValue.Replace(hdi.pszText,sText); } } sTextAll.TrimLeft(); sTextAll.TrimRight(); if (sTextAll.IsEmpty()) { sValue = _T(""); } return TRUE; } BOOL CExcelWrite::ScriptToCells(LPCTSTR pszScript,CStringArray& arCells) { CString sScript = pszScript; sScript.TrimLeft(); sScript.TrimRight(); int nIndex = -1; CString sCell; while(TRUE) { sScript.TrimLeft(); sScript.TrimRight(); nIndex = sScript.Find(_T(","),0); if (nIndex != -1) { sCell = sScript.Mid(0,nIndex); //去掉空格 sCell.TrimLeft(); sCell.TrimRight(); arCells.Add(sCell); if (nIndex + 1 < sScript.GetLength()) { sCell = sScript.Mid(nIndex + 1); //去掉空格 sCell.TrimLeft(); sCell.TrimRight(); sScript = sCell; } else { break; } } else { if (sScript.GetLength() > 0) { arCells.Add(sCell); } break; } } return arCells.GetSize() > 0; }