I am doing something similar and ran into the same error with varchar(max) data types that come from SQL Server. It doesn't matter where the data is coming from though. When you get the data from your database, you need to define the schema for the column data types and sizes. I do this by calling FillSchema on the data adapter that I am using -
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
da.FillSchema(dt, SchemaType.Source);
return dt;
You could also set the column properties individually, if you wanted.
Then I loop through each column in my DataTable and set up my columns for export with oleDB using ADOX.NET. You don't have to use ADOX.NET, the main concept here is to use the sizes that came from the original database.
foreach (DataColumn col in dt.Columns)
{
columnList.Append(dt.TableName + "." + col.ColumnName + ", ");
ADOX.Column adoxCol = new Column();
adoxCol.ParentCatalog = cat;
adoxCol.Name = col.ColumnName;
adoxCol.Type = TranslateType(col.DataType, col.MaxLength);
int size = col.MaxLength > 0 ? col.MaxLength : 0;
if (col.AllowDBNull)
{
adoxCol.Attributes = ColumnAttributesEnum.adColNullable;
}
adoxTable.Columns.Append(adoxCol, adoxCol.Type, size);
}
Here is a snippet from my TranslateType method that determines whether or not to use the LongVarWChar or VarWChar. These data types are the ADOX.NET version of the oleDB data types. I believe that anything over 4000 characters should use the LongVarWChar type but I'm not sure about that. You didn't mention which version of Excel is your target, but I have this working with both Excel 2003 and Excel 2007.
case "System.String":
if (maxLength > 4000)
{
return DataTypeEnum.adLongVarWChar;
}
return DataTypeEnum.adVarWChar;
The LongVarWChar can take large sizes that can accomadate 2 GB. So don't worry about making the size too big.