最近这段时间一直在琢磨将图片和GridView里的数据一块导入Excel,并保存到客户端磁盘上。试验了好几种方法,要不就是只能将图片插入Excel中,要不只能将GridView的数据导入到Excel,两者总是不能一块实现,一个大的原因就是GridView中存在复杂表头、上下标等问题。
下面就讲一下如何将图片和GridView中的单行简单表头导入到Excel中,也是参照了网上高手将GridView中的数据导出到Excel中的方法,然后又通过自己的努力实现自己最终需要的导出Excel功能。客户之所以提出这样的需求,主要是因为一个网页的上面部分实现主要数据的图形绘制,下面通过表格实现详细数据的显示。如果采用水晶报表开发,这样的功能很容易实现。但是水晶报表在绘制一些特殊的图形时存在不能满足客户的需求,显示的效果也不尽人意,所以就借助的第三方Dundas Chart控件开发了图形。
导出Excel代码如下:
代码
1 /// <summary> 2 /// 导出Excel,并保存本地 3 /// </summary> 4 /// <param name="dt">数据表DataTable</param> 5 /// <param name="AbosultedFilePath">图片、Excel文件保存路径</param> 6 /// <param name="fileName">文件名称</param> 7 /// <param name="cWidth">图片宽度</param> 8 /// <param name="cHeight">图片高度</param> 9 /// <returns>返回true</returns> 10 public static bool ExportToExcel(DataTable dt, string AbosultedFilePath, string fileName, float cWidth, float cHeight) 11 { 12 object m_objOpt = System.Reflection.Missing.Value; 13 14 //检查数据表是否为空,如果为空,则退出 15 if (dt == null) 16 return false; 17 18 //创建Excel应用程序对象,如果未创建成功则退出 19 Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application(); 20 if (xlApp == null) 21 { 22 System.Web.HttpContext.Current.Response.Write("无法创建Excel对象,可能你的电脑未装Excel"); 23 return false; 24 } 25 26 Microsoft.Office.Interop.Excel.Workbooks workbooks = xlApp.Workbooks; 27 Microsoft.Office.Interop.Excel.Workbook workbook = workbooks.Add(Microsoft.Office.Interop.Excel.XlWBATemplate.xlWBATWorksheet); 28 Microsoft.Office.Interop.Excel.Worksheet worksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Worksheets[1]; //取得sheet1 29 Microsoft.Office.Interop.Excel.Range range = null; 30 31 //---插入图片第一种方法---// 32 //range = worksheet.get_Range("A1", m_objOpt); //A1:代表Excel中单元格位置 33 //range.Select(); 34 //Excel.Pictures pics = (Excel.Pictures)worksheet.Pictures(m_objOpt); 35 //pics.Insert(AbosultedFilePath + fileName + ".jpg", m_objOpt); 36 37 //---插入图片第二中方法---// 38 worksheet.Shapes.AddPicture(AbosultedFilePath + fileName + ".jpg", MsoTriState.msoFalse, MsoTriState.msoTrue, 2, 2, cWidth, cHeight); 39 40 object aa = worksheet.Rows.Height; 41 long totalCount = dt.Rows.Count; 42 long rowRead = 0; 43 float percent = 0; 44 //定义图片所占的行数 45 int rowIndex = Convert.ToInt32(cHeight / 13.5) + 2; 46 //定义存放表头名称的数组 47 ArrayList arrheadName = new ArrayList(); 48 string cellText = ""; 49 50 //---获取dt中表头的名称,也可以换成获取GridView中表头的名称---// 51 arrheadName.Clear(); 52 for(int col=0;col<dt.Columns.Count;col++) 53 { 54 arrheadName.Add(dt.Columns[col].ColumnName); 55 } 56 57 //写入标题 58 for (int i = 0; i < arrheadName.Count; i++) 59 { 60 //写入表头名称 61 worksheet.Cells[rowIndex, i + 1] = arrheadName[i].ToString(); 62 63 //设置标题的样式 64 range = (Microsoft.Office.Interop.Excel.Range)worksheet.Cells[rowIndex, i + 1]; 65 range.Font.Bold = true; //粗体 66 range.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter; //居中 67 range.WrapText = true;//换行 68 range.BorderAround(Microsoft.Office.Interop.Excel.XlLineStyle.xlContinuous, Microsoft.Office.Interop.Excel.XlBorderWeight.xlThin, Microsoft.Office.Interop.Excel.XlColorIndex.xlColorIndexAutomatic, null); //背景色 69 //range.Borders[Microsoft.Office.Interop.Excel.XlBordersIndex.xlInsideHorizontal].Weight = Microsoft.Office.Interop.Excel.XlBorderWeight.xlThin; 70 range.EntireColumn.AutoFit(); //自动设置列宽 71 range.EntireRow.AutoFit(); //自动设置行高 72 } 73 74 //写入DataTable中数据的内容 75 for (int r = 0; r < dt.Rows.Count; r++) 76 { 77 for (int c = 0; c < dt.Columns.Count; c++) 78 { 79 //写入内容 80 worksheet.Cells[r + rowIndex + 1, c + 1] = dt.Rows[r][c].ToString(); 81 //设置样式 82 range = (Microsoft.Office.Interop.Excel.Range)worksheet.Cells[r + rowIndex + 1, c + 1]; 83 range.Font.Size = 9; //字体大小 84 range.BorderAround(Microsoft.Office.Interop.Excel.XlLineStyle.xlContinuous, Microsoft.Office.Interop.Excel.XlBorderWeight.xlThin, Microsoft.Office.Interop.Excel.XlColorIndex.xlColorIndexAutomatic, null); //加边框 85 range.EntireColumn.AutoFit(); //自动调整列宽 86 } 87 rowRead++; 88 percent = ((float)(100 * rowRead)) / totalCount; 89 System.Windows.Forms.Application.DoEvents(); 90 } 91 range.Borders[Microsoft.Office.Interop.Excel.XlBordersIndex.xlInsideHorizontal].Weight = Microsoft.Office.Interop.Excel.XlBorderWeight.xlThin; 92 if (dt.Columns.Count > 1) 93 { 94 range.Borders[Microsoft.Office.Interop.Excel.XlBordersIndex.xlInsideVertical].Weight = Microsoft.Office.Interop.Excel.XlBorderWeight.xlThin; 95 } 96 97 try 98 { 99 //---首先将Excel保存到服务器文件夹中---//100 workbook.Saved = true;101 workbook.SaveCopyAs(AbosultedFilePath + fileName + ".xls");102 103 }104 catch (Exception ex)105 {106 System.Web.HttpContext.Current.Response.Write("导出文件时出错,文件可能正被打开!n" + ex.ToString());107 return false;108 }109 110 workbooks.Close();111 112 if (xlApp != null)113 {114 xlApp.Workbooks.Close();115 xlApp.Quit();116 117 int generation = System.GC.GetGeneration(xlApp);118 System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);119 120 xlApp = null;121 System.GC.Collect(generation);122 }123 GC.Collect(); //强行销毁124 125 #region 强行杀死最近打开的Excel进程126 System.Diagnostics.Process[] excelProc = System.Diagnostics.Process.GetProcessesByName("EXCEL");127 System.DateTime startTime = new DateTime();128 int m, killID = 0;129 for (m = 0; m < excelProc.Length; m++)130 {131 if (startTime < excelProc[m].StartTime)132 {133 startTime = excelProc[m].StartTime;134 killID = m;135 }136 }137 if (excelProc[killID].HasExited == false)138 {139 excelProc[killID].Kill();140 }141 #endregion142 143 //---删除控件保存的图片---//144 if (File.Exists(AbosultedFilePath + fileName + ".jpg"))145 {146 File.Delete(AbosultedFilePath + fileName + ".jpg");147 }148 //---将保存的Excel下载到本地---//149 if (saveExcel(AbosultedFilePath + fileName + ".xls"))150 {151 return true;152 }153 return false;154 }155 156 /// <summary>157 /// Excel文件下载本地磁盘158 /// </summary>159 /// <param name="FileName">路径+文件名</param>160 /// <returns>返回true</returns>161 public static bool saveExcel(string FileName)162 {163 try164 {165 string FullFileName = FileName;166 //FileName--要下载的文件名 167 FileInfo DownloadFile = new FileInfo(FullFileName);168 if (DownloadFile.Exists)169 {170 System.Web.HttpContext curContext = System.Web.HttpContext.Current;171 curContext.Response.Clear();172 curContext.Response.ClearHeaders();173 curContext.Response.Buffer = false;174 curContext.Response.ContentType = "application/octet-stream";175 curContext.Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(DownloadFile.FullName, System.Text.Encoding.ASCII));176 curContext.Response.AppendHeader("Content-Length", DownloadFile.Length.ToString());177 curContext.Response.WriteFile(DownloadFile.FullName);178 curContext.Response.Flush();179 curContext.Response.End();180 DownloadFile.Delete();// 这个删除无作用181 return true;182 }183 else184 {185 //文件不存在186 return false;187 }188 }189 catch190 {191 //打开时异常了192 return false;193 }194 }
通过上面的方法导出Excel后,打开Excel发现了一个问题,图片的高度和宽度是按像素取值,但是保存到Excel中明显看到图片被放大了,查看图片的大小和属性,发现高度和宽度都变成了133%,查了好久也不知道是什么原因造成的,最终只能试着将传入图片的高度和宽度进行了处理:
float width = Convert.ToSingle(cWidth - cWidth * 0.25);//cWidth:图片宽度
float height = Convert.ToSingle(cHeight - cHeight * 0.25);//cHeight :图片高度
经过这样,插入的图片才达到了原始效果。有没有高手遇到这种情况的,指导一下~~~
需要注意的地方:
在调用ExportToExcel();这个方法后,要记得删除服务器 path + fileName + ".xls" 这个临时文件,不然会占用大量磁盘空间。
path:服务器保存的目录
fileName:文件名称
另外一种导出Excel的方法:
就是先将Excel文件保存成xml文件,然后通过解析xml文件实现将复杂表头和数据导出到Excel文件,但是目前还没有将图片采用这种方式导出到Excel中,不知道可不可以将图片采用文件流的形式写入到Excel中,如果有专家曾经做过这样的,指导一下。
如果有人遇到以上问题,或者做过类似的,欢迎交流、指导~~~
宝贵知识就是拿来分享 促使共同进步 节省他人时间就是在节省自己时间~~~
原文链接: https://www.cnblogs.com/ZHF/archive/2010/09/17/1829012.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/15124
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!