I am using the following code to export a dataset from c# to excel. I am getting the following output:
ABC | 1 | 2/15/2011 21:36 | Systems Analyst | Project Duration
ABC | 1 | 2/15/2011 21:36 | Systems Analyst | Skill of Team
ABC | 1 | 2/15/2011 21:36 | Systems Analyst | Process
What I would like to do, however, is output data in the following format, and add column headings. I would like to display NEGATIVE if the output for StoryCategoryID is 1 and POSITIVE if the output is 0. Please help!
Story | Story Type | Date | Project Member | Tag 1 | Tag 2 | Tag 3
ABC | Negative | 2/15/2011 21:36 | Project Duration | Skill of Team | Process
Code:
protected void btnExcelExport_Click(object sender, EventArgs e)
{
string sql = null;
string data = null;
//string path = save_as.Text;
int i = 0;
int j = 0;
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
object misValue = System.Reflection.Missing.Value;
xlApp = new Excel.ApplicationClass();
xlWorkBook = xlApp.Workbooks.Add(misValue);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
//开发者_JAVA百科connectionString = "data source=servername;initial catalog=databasename;user id=username;password=password;";
SqlConnection cnn = new SqlConnection(GetConnectionString());
cnn.Open();
sql = "SELECT s.Story, s.StoryCategoryID, s.CreationDate, m.CompanyRole, af.Name FROM Story s INNER JOIN ProjectIterationMember pm ON pm.ProjectIterationMemberID = s.ProjectIterationMemberID INNER JOIN Iterations i ON i.ProjectIterationID = pm.ProjectIterationID INNER JOIN Member m ON m.MemberID = pm.MemberID INNER JOIN ProjectStoryFactors psf ON psf.StoryID = s.StoryID INNER JOIN AgileFactors af ON af.AgileFactorID = psf.AgileFactorID WHERE i.ProjectID = '" + proj_id + "'";
SqlDataAdapter dscmd = new SqlDataAdapter(sql, cnn);
DataSet ds = new DataSet();
dscmd.Fill(ds);
for (i = 0; i <= ds.Tables[0].Rows.Count - 1; i++)
{
for (j = 0; j <= ds.Tables[0].Columns.Count - 1; j++)
{
data = ds.Tables[0].Rows[i].ItemArray[j].ToString();
xlWorkSheet.Cells[i + 1, j + 1] = data;
}
}
xlWorkBook.SaveAs("excelDocument" + DateTime.Now.Ticks + ".xls", Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
xlWorkBook.Close(true, misValue, misValue);
xlApp.Quit();
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlApp);
//MessageBox.Show("Excel file created , you can find the file c:\\csharp.net-informations.xls");
}
First of all, performance-wise, it's a lot faster to write to a range in Excel then to write cell by cell. You can do this by creating a 2-dimensional array from the data in your table and write it directly to a range.
About the headers: Just write the text you want in the first row of Excel. You can even set the AutoFilter if you like. When writing your data, you start from row 2.
For the change of the value to "Positive" or "Negative": do this before starting to write to excel. Just change the values in the source (the array of another datatable if you like).
//Create 2-dimensional array with the data from the datatable
DataTable dt = ds.Tables[0];
string[,] arrValues = new string[dt.Rows.Count, dt.Columns.Count];
for (int i = 0; i < dt.Rows.Count; i++)
{
for (int j = 0; j < dt.Columns.Count; j++)
{
arrValues[i, j] = dt.Rows[i].ItemArray[j].ToString();
}
}
//Change the data from the column StoryCategoryID here
//Just loop through the items in the correct column of the array
//and check whether it's "0" or "1"
//Add headers
for (int i = 0; i < dt.Columns.Count; i++)
{
xlWorkSheet.Cells[1, i + 1] = dt.Columns[i].ColumnName;
//Or any name you like
}
//Create range (start at row 2 because of header-row)
Range xlRange = (Range)xlWorkSheet.Cells[2, 1];
xlRange = xlRange.Resize[dt.Rows.Count, dt.Columns.Count];
//Fill range
xlRange.Value = arrValues;
//Format document
xlWorkSheet.EnableAutoFilter = true;
xlWorkSheet.Cells.AutoFilter(1);
xlWorkSheet.Range["A1", "A1"].EntireRow.Font.Bold = true;
xlWorkSheet.Columns.AutoFit();
The reason why I use a range in stead of passing the values cell by cell is due to performance. For about 1500 records (15 coloumns) it took about 7 or 8 minutes to create an Excel-file, when doing it this way (with a range) it took about 5 or 10 seconds.
(This was some VB.Net-code I've converted out of my mind, so maybe there could be some "misValue" you have to pass with other parameters, but you get the picture, I think.)
精彩评论