Just loop through the rows and columns of the list control:
void CMyListCtrl::GetHeaderItemText(CString& str, int nItem) const
{
TCHAR lpBuffer[256] = _T("");
LVCOLUMN lvc;
memset(&lvc, 0, sizeof(LVCOLUMN));
lvc.mask = LVCF_TEXT;
lvc.pszText = lpBuffer;
lvc.cchTextMax = 256;
VERIFY(GetColumn(nItem, &lvc));
str = lpBuffer;
}
bool CMyListCtrl::WriteCSV(LPCTSTR lpszFile, bool bHeader) const
{
FILE *f = _tfopen(lpszFile, _T("wb"));
if (NULL == f)
return false;
int nRows = GetItemCount();
int nColumns = GetHeaderCtrl()->GetItemCount();
if (bHeader)
{
for (int j = 0; j < nColumns; j++)
{
int k = GetHeaderCtrl()->OrderToIndex(j);
if (j)
fprintf(f, ",");
CString strItem;
GetHeaderItemText(strItem, k);
#ifdef _UNICODE
CStringA strItemA(strItem.GetString());
fprintf(f, "\"%s\"", strItemA.GetString());
#else
fprintf(f, "\"%s\"", strItem.GetString());
#endif
}
fprintf(f, "\r\n");
}
for (int i = 0; i < nRows; i++)
{
for (int j = 0; j < nColumns; j++)
{
int k = GetHeaderCtrl()->OrderToIndex(j);
if (j)
fprintf(f, ",");
CString strItem = GetItemText(i, k);
#ifdef _UNICODE
CStringA strItemA(strItem.GetString());
fprintf(f, "\"%s\"", strItemA.GetString());
#else
fprintf(f, "\"%s\"", strItem.GetString());
#endif
}
fprintf(f, "\r\n");
}
fclose(f);
return true;
}
This exports ANSI text with Unicode builds. Most applications expect ANSI files when importing CSV.
The code may be enhanced:
- UPDATE: Must escape quote chars when they occur in cells,
- Optional use single quotes.
- Optional use other delimiter character (e.g. ';').
- Quote only cells that contain the quote or the delimiter character.
- Optional exclude hidden columns (columns with width 0).
- Optional export only selected rows.