C#操作word之插入图片

标签:
无奈命令个人信息区域组件 |
分类: C# |
假如我们导出一份简历到word文档,那势必可能要同时导出我们包含的简历,下面就来试一下如何和通过C#代码,将图片插入到word文档中。
为了简便起见,就简单一点。类似下面这样的
姓名 | 张三 |
照片 | |
protected void InsertPtctureToExcel() { Word.Application app = null; Word.Document doc = null; try { object oMissing = System.Reflection.Missing.Value; //图片地址 string fileName =Server.MapPath("photo.jpg"); object linkToFile = false; object saveWithDocument = true; app = new Word.Application(); doc = app.Documents.Add(); Word.Table table = doc.Tables.Add(app.Selection.Range, 2, 2); table.Columns[1].Width = 100f; table.Columns[2].Width = 125f; table.Cell(1, 1).Range.Text = "姓名"; table.Cell(1, 2).Range.Text = "张三"; table.Cell(2,1).Range.Text = "照片"; table.Cell(2, 2).Select(); object range = app.Selection.Range; Word.InlineShape shape = app.ActiveDocument.InlineShapes.AddPicture(fileName, ref linkToFile, ref saveWithDocument, ref range); shape.Width = 100f;//图片宽度 shape.Height = 120f;//图片高度 shape.ConvertToShape().WrapFormat.Type = Word.WdWrapType.wdWrapSquare;//四周环绕的方式 string newFile = DateTime.Now.ToString("yyyyMMddHHmmssss") + ".doc"; string physicNewFile = Server.MapPath(newFile); doc.SaveAs(physicNewFile); } catch (Exception ex) { } finally { if (doc != null) { doc.Close();//关闭文档 } if (app != null) { app.Quit();//退出应用程序 } } }
假如我们需要在一个word文档的某个位置插入一张表格,而且要对这一张表格中的单元格做拆分合并,之类的。
先看下效果,先不管表格是否合理,总之就是要这样的统计文档,但是人数,班级数都是不确定的,也就是表格是根据数据动态生成的,
这样我们就很难用之前的替换方式来实现,也就是要动态来创建表格。
班级 | 姓名 | 成绩 | 人数总计 | 班主任 |
一班 | 张三 | 498 | 1 | 小李 |
二班 | 李四 | 354 | 2 | 陈飞 |
小红 | 502 | |||
三班 | 丁爽 | 566 | 1 | 王林 |
1、用单元格拆分的方式实现,也就是根据有多少班级,则增加多少行,针对于其中的学生信息再对单元格进行拆分。
/// /// 数据实体类 /// public class Student { public string Name;//姓名 public int Score;//成绩 public string StuClass;//班级 public string Leader;//班主任 } /// /// 动态创建table到word /// protected void CreateTableToExcel() { Word.Application app = null; Word.Document doc = null; try { //构造数据 List datas = new List(); datas.Add(new Student{ Leader="小李", Name="张三", Score=498, StuClass="一班"}); datas.Add(new Student{ Leader="陈飞", Name="李四", Score=354, StuClass="二班"}); datas.Add(new Student{ Leader="陈飞", Name="小红", Score=502, StuClass="二班"}); datas.Add(new Student{ Leader="王林", Name="丁爽", Score=566, StuClass="三班"}); var cate = datas.GroupBy(s=>s.StuClass); int rows = cate.Count()+1;//表格行数加1是为了标题栏 int cols = 5;//表格列数 object oMissing = System.Reflection.Missing.Value; app = new Word.Application();//创建word应用程序 doc = app.Documents.Add();//添加一个word文档 //输出大标题加粗加大字号水平居中 app.Selection.Font.Bold = 700; app.Selection.Font.Size = 16; app.Selection.Range.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter; app.Selection.Text = "班级成绩统计单"; //换行添加表格 object line = Word.WdUnits.wdLine; app.Selection.MoveDown(ref line, oMissing, oMissing); app.Selection.TypeParagraph();//换行 Word.Range range = app.Selection.Range; Word.Table table = app.Selection.Tables.Add(range, rows, cols, ref oMissing, ref oMissing); //设置表格的字体大小粗细 table.Range.Font.Size = 10; table.Range.Font.Bold=0; //设置表格标题 int rowIndex = 1; table.Cell(rowIndex, 1).Range.Text = "班级"; table.Cell(rowIndex, 2).Range.Text = "姓名"; table.Cell(rowIndex, 3).Range.Text = "成绩"; table.Cell(rowIndex, 4).Range.Text = "人数"; table.Cell(rowIndex, 5).Range.Text = "班主任"; //循环数据创建数据行 rowIndex++; foreach (var i in cate) { table.Cell(rowIndex, 1).Range.Text = i.Key;//班级 table.Cell(rowIndex, 4).Range.Text = i.Count().ToString();//人数 table.Cell(rowIndex, 5).Range.Text = i.First().Leader;//班主任 table.Cell(rowIndex,2).Split(i.Count(), 1);//分割名字单元格 table.Cell(rowIndex,3).Split(i.Count(), 1);//分割成绩单元格 //对表格中的班级、姓名,成绩单元格设置上下居中 table.Cell(rowIndex, 1).VerticalAlignment = Word.WdCellVerticalAlignment.wdCellAlignVerticalCenter; table.Cell(rowIndex, 4).VerticalAlignment = Word.WdCellVerticalAlignment.wdCellAlignVerticalCenter; table.Cell(rowIndex, 5).VerticalAlignment = Word.WdCellVerticalAlignment.wdCellAlignVerticalCenter; //构建姓名,成绩数据 foreach (var x in i) { table.Cell(rowIndex, 2).Range.Text = x.Name; table.Cell(rowIndex, 3).Range.Text = x.Score.ToString(); rowIndex++; } } //导出到文件 string newFile = DateTime.Now.ToString("yyyyMMddHHmmssss") + ".doc"; string physicNewFile = Server.MapPath(newFile); doc.SaveAs(physicNewFile, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing); } catch(Exception ex) { } finally { if (doc != null) { doc.Close();//关闭文档 } if (app != null) { app.Quit();//退出应用程序 } } }
则必须排除在外,否则会出现”此命令无效“的异常,所以下面代码在合并的时候做了一个判断。
protected void CreateTableToExcel2() { Word.Application app = null; Word.Document doc = null; try { //构造数据 List datas = new List(); datas.Add(new Student { Leader = "小李", Name = "张三", Score = 498, StuClass = "一班" }); datas.Add(new Student { Leader = "陈飞", Name = "李四", Score = 354, StuClass = "二班" }); datas.Add(new Student { Leader = "陈飞", Name = "小红", Score = 502, StuClass = "二班" }); datas.Add(new Student { Leader = "王林", Name = "丁爽", Score = 566, StuClass = "三班" }); var cate = datas.GroupBy(s => s.StuClass); int rows = datas.Count + 1; int cols = 5;//表格列数 object oMissing = System.Reflection.Missing.Value; app = new Word.Application();//创建word应用程序 doc = app.Documents.Add();//添加一个word文档 //输出大标题加粗加大字号水平居中 app.Selection.Font.Bold = 700; app.Selection.Font.Size = 16; app.Selection.Range.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter; app.Selection.Text = "班级成绩统计单"; //换行添加表格 object line = Word.WdUnits.wdLine; app.Selection.MoveDown(ref line, oMissing, oMissing); app.Selection.TypeParagraph();//换行 Word.Range range = app.Selection.Range; Word.Table table = app.Selection.Tables.Add(range, rows, cols, ref oMissing, ref oMissing); //设置表格的字体大小粗细 table.Range.Font.Size = 10; table.Range.Font.Bold = 0; //设置表格标题 int rowIndex = 1; table.Cell(rowIndex, 1).Range.Text = "班级"; table.Cell(rowIndex, 2).Range.Text = "姓名"; table.Cell(rowIndex, 3).Range.Text = "成绩"; table.Cell(rowIndex, 4).Range.Text = "人数"; table.Cell(rowIndex, 5).Range.Text = "班主任"; //循环数据创建数据行 rowIndex++; foreach (var i in cate) { int moveCount = i.Count() - 1;//纵向合并行数 if (moveCount.ToString() != "0") { table.Cell(rowIndex, 1).Merge(table.Cell(rowIndex + moveCount, 1));//合并班级 table.Cell(rowIndex, 4).Merge(table.Cell(rowIndex + moveCount, 4));//合并人数 table.Cell(rowIndex, 5).Merge(table.Cell(rowIndex + moveCount, 5));//合并班主任 } //写入合并的数据并垂直居中 table.Cell(rowIndex, 1).Range.Text = i.Key; table.Cell(rowIndex, 4).Range.Text = i.Count().ToString(); table.Cell(rowIndex, 5).Range.Text = i.First().Leader; table.Cell(rowIndex, 1).VerticalAlignment = Word.WdCellVerticalAlignment.wdCellAlignVerticalCenter; table.Cell(rowIndex, 4).VerticalAlignment = Word.WdCellVerticalAlignment.wdCellAlignVerticalCenter; table.Cell(rowIndex, 5).VerticalAlignment = Word.WdCellVerticalAlignment.wdCellAlignVerticalCenter; //构建姓名,成绩数据 foreach (var x in i) { table.Cell(rowIndex, 2).Range.Text = x.Name; table.Cell(rowIndex, 3).Range.Text = x.Score.ToString(); rowIndex++; } } //导出到文件 string newFile = DateTime.Now.ToString("yyyyMMddHHmmssss") + ".doc"; string physicNewFile = Server.MapPath(newFile); doc.SaveAs(physicNewFile, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing); } catch (Exception ex) { } finally { if (doc != null) { doc.Close();//关闭文档 } if (app != null) { app.Quit();//退出应用程序 } } }
在编写word文档的时候常常需要我们输入特殊的符号,比如选择框,打上勾的选择框,或者其他一些特殊字符,如下
http://images.cnitblog.com/blog/89844/201306/16110110-dd16489916ab47968f9b331a51876915.png
一般来说有些字符,其实直接按照原样复制一个,作为替换字符就行了,就像我们上面的最后一个方框,其实可以复制直接粘贴单VS的编辑器中,但是一些
比较特殊的字符,复制到VS的编辑器中是不管用的,最后什么都看不到,对于那些我们就要用其他办法了。总之如果可以直接让其在VS编辑器当做字符显示出来,
那就不要特殊方法了(其实很多字符我们可以通过一些搜狗输入法的,特殊字符选择)
当我们要在word中输入选择框和打钩的选择框,我们可以这样:插入->符号->字体选择“Wingdings 2”。里面就有我们需要的选择框,
http://images.cnitblog.com/blog/89844/201306/16111854-971283db3ee1416fba4bdb25aace1495.png
这里我们看到我们需要的打钩选择框的,字体是Wingdings 2,然后16进制的字符代码是0052,这样我们就可以利用这个来实现我们需要的字符
用之前同样的模板但是我们希望在性别这一栏采用选中框的方式展现效果,类似这样的
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
/// /// 替换word中的文本,并导出word,输出选择框 /// protected void ReplaceToExcel() { Word.Application app = null; Word.Document doc = null; //将要导出的新word文件名 string newFile = DateTime.Now.ToString("yyyyMMddHHmmssss") + ".doc"; string physicNewFile = Server.MapPath(DateTime.Now.ToString("yyyyMMddHHmmssss") + ".doc"); try { app = new Word.Application();//创建word应用程序 object fileName = Server.MapPath("template.doc");//模板文件 //打开模板文件 object oMissing = System.Reflection.Missing.Value; doc = app.Documents.Open(ref fileName, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing); //构造数据 Dictionary<<SPAN style="COLOR: #0000ff">string, string> datas = new Dictionary<<SPAN style="COLOR: #0000ff">string, string>(); datas.Add("{name}", "张三"); datas.Add("{sex}", "男"); datas.Add("{provinve}", "浙江"); datas.Add("{address}", "浙江省杭州市"); datas.Add("{education}", "本科"); datas.Add("{telephone}", "12345678"); datas.Add("{cardno}", "123456789012345678"); object replace = Word.WdReplace.wdReplaceAll; foreach (var item in datas) { app.Selection.Find.Replacement.ClearFormatting(); app.Selection.Find.ClearFormatting(); app.Selection.Find.Text = item.Key;//需要被替换的文本 if (item.Key == "{sex}") { app.Selection.Find.Replacement.Font.Name = "Wingdings 2";//这里设置字体类型 //Wingdings 2字体下的\u0052代表打钩的选择框,\u00A3代表未打钩的选择框 if (item.Value == "男") { app.Selection.Find.Replacement.Text = "\u0052男\u00A3女"; } else { app.Selection.Find.Replacement.Text = "\u00A3男\u0052女"; } } else { app.Selection.Find.Replacement.Text = item.Value;//替换文本 } //执行替换操作 app.Selection.Find.Execute( ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref replace, ref oMissing, ref oMissing, ref oMissing, ref oMissing); } //对替换好的word模板另存为一个新的word文档 doc.SaveAs(physicNewFile, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing); } catch (Exception ex) { } finally { if (doc != null) { doc.Close();//关闭word文档 } if (app != null) { app.Quit();//退出word应用程序 } } }
☏
之前我们采用Find.Replacement.Text的方式对word模板上的内容进行替换,Replacement是专门为文本替换而生,但是当我们替换的内容超过一定字符数会出现“字符串参量过长。”异常错误。所以本节我们采用TypeText('字符')来代替原来的Find.Replacement.Text,因为TypeText专职用来写文本用的,所以不会因为字符数影响。
我们还是采用之前的例子,对用户的一个登记信息导入到word,有一个人信息介绍的单元格,该信息很容易超过500个字符
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
个人信息介绍 | aaaaaaaaaaaa…… |
还是先准备类似的word模板
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
个人信息介绍 | |
下面上代码
/// /// 用TypeText替换word中的文本 /// protected void TypeTextToExcel() { Word.Application app = null; Word.Document doc = null; //新的word文档路径 string newFile = DateTime.Now.ToString("yyyyMMddHHmmssss") + ".doc"; string physicNewFile = Server.MapPath(newFile); try { object oMissing = System.Reflection.Missing.Value; //模板文档 object fileName = Server.MapPath("template.doc"); app = new Word.Application();//创建word应用程序 //打开模板word文档 doc = app.Documents.Open(ref fileName, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing); //构造数据 Dictionary<<SPAN style="COLOR: #0000ff">string, string> datas = new Dictionary<<SPAN style="COLOR: #0000ff">string, string>(); datas.Add("{name}", "张三"); datas.Add("{sex}", "男"); datas.Add("{provinve}", "浙江"); datas.Add("{address}", "浙江省杭州市"); datas.Add("{education}", "本科"); datas.Add("{telephone}", "12345678"); datas.Add("{cardno}", "123456789012345678"); datas.Add("{info}", new String('a',500));//构造大数据字段 foreach (var item in datas) { app.Selection.Find.ClearFormatting(); app.Selection.Find.Text = item.Key;//需要查找的字符 app.Selection.Find.Execute(); //只负责找到匹配字符 app.Selection.TypeText(item.Value);//在找到的字符区域写数据 } //另存word文档 doc.SaveAs(physicNewFile, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing); } catch(Exception ex) { } finally { if (doc != null) { doc.Close();//关闭文档 } if (app != null) { app.Quit();//退出应用程序 } } }
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
假设我们需要将客户的信息导成word文档,其格式类似上面这样的。 我们可以先准备一个word模板,格式如下
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
这里要替换的内容,我们可以定义成数据库中对应的字段,这里为了看上去清晰将要替换的内容用{字段}来代替,你也可以用其他你想要
的方式来定义。
接下来看实现的方式(记得首先在引用中添加相应的组件哦!)
public partial class WebForm3 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { ReplaceToExcel(); } /// /// 替换word中的文本,并导出word /// protected void ReplaceToExcel() { Word.Application app = null; Word.Document doc = null; //将要导出的新word文件名 string newFile = DateTime.Now.ToString("yyyyMMddHHmmssss") + ".doc"; string physicNewFile = Server.MapPath(DateTime.Now.ToString("yyyyMMddHHmmssss") + ".doc"); try { app = new Word.Application();//创建word应用程序 object fileName = Server.MapPath("template.doc");//模板文件 //打开模板文件 object oMissing = System.Reflection.Missing.Value; doc = app.Documents.Open(ref fileName, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing); //构造数据 Dictionary<<SPAN style="COLOR: #0000ff">string, string> datas = new Dictionary<<SPAN style="COLOR: #0000ff">string, string>(); datas.Add("{name}", "张三"); datas.Add("{sex}", "男"); datas.Add("{provinve}", "浙江"); datas.Add("{address}", "浙江省杭州市"); datas.Add("{education}", "本科"); datas.Add("{telephone}", "12345678"); datas.Add("{cardno}", "123456789012345678"); object replace = Word.WdReplace.wdReplaceAll; foreach (var item in datas) { app.Selection.Find.Replacement.ClearFormatting(); app.Selection.Find.ClearFormatting(); app.Selection.Find.Text = item.Key;//需要被替换的文本 app.Selection.Find.Replacement.Text = item.value;//替换文本 //执行替换操作 app.Selection.Find.Execute( ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref replace, ref oMissing, ref oMissing, ref oMissing, ref oMissing); } //对替换好的word模板另存为一个新的word文档 doc.SaveAs(physicNewFile, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing); //准备导出word Response.Clear(); Response.Buffer = true; Response.Charset = "utf-8"; Response.AddHeader("Content-Disposition", "attachment;filename=" + DateTime.Now.ToString("yyyyMMddHHmmssss") + ".doc"); Response.ContentEncoding = System.Text.Encoding.GetEncoding("utf-8"); Response.ContentType = "application/ms-word"; Response.End(); } catch (System.Threading.ThreadAbortException ex) { //这边为了捕获Response.End引起的异常 } catch (Exception ex) { } finally { if (doc != null) { doc.Close();//关闭word文档 } if (app != null) { app.Quit();//退出word应用程序 } //如果文件存在则输出到客户端 if (File.Exists(physicNewFile)) { Response.WriteFile(physicNewFile); } } } }
当我们对一个表建立一个主键时,默认会给该主键列添加一条聚集索引,这是数据库内部自动建立的,唯一性约束也会默认创建一个非聚集索引。
create table MyTable ( id int identity(1,1) primary key, name nvarchar(10) unique ) exec sp_helpindex MyTable
上面我们建立了一个主键id 和唯一性约束的name列,查看表可以看到这时产生了两个索引
聚集索引是一个宝贵的资源,在一些表的中有时我们永远不会用到主键来作为查询条件,或者作为其他表的外键,这时主键的聚集索引
就显得大才小用了,我们希望将聚集索引建立在其他真正需要的字段,不过当我们执行删除操作时会报以下错误
消息 3723,级别 16,状态 4,第 1
行
不允许对索引
'MyTable.PK__MyTable__3213E83F145C0A3F' 显式地使用 DROP INDEX。该索引正用于
PRIMARY KEY 约束的强制执行
不过我们可以先删除主键约束,这样聚集所以就自动删除了
alter table MyTable drop constraint PK__MyTable__3213E83F145C0A3F
我们再看下聚集索引已经不存在了
http://images.cnitblog.com/blog/89844/201306/07220412-f61d647631284703a6f14382f5bd97a7.png
当然唯一约束所引起的索引也可以同样的方式操作,先删除唯一约束
ASP.NET MVC的应用程序生命周期还是跟原来ASP.NET
WebForm一样没有区别,只是引入MVC后,加了一个UrlRoutingModule模块,该模块用来捕获应用程序生命周期中的PostResolveRequestCache事件,当事件触发时然后选择合适的IHttpHandler来处理请求
那是如何获取IHttpHandler的呢,我们在Global.asax的Application_Start事件中写routes.MapRoute注册路由时,会给路由对象Route创建一个MvcRouteHandler,该对象调用GetHttpHandler方法返回MvcHandler
对象用来处理接下来的操作。我们看到这个处理程序已经不是原来WebForm时的Page了。
获取完IHttpHandler后应用程序生命周期继续往下执行,经过一些事件后最后终于触发了CallHandlerExecutionStep
MvcHandler是一个IHttpAsyncHandler,它是一个异步的,因此它不是执行ProcessRequest方法了,取而代之的是BeginProcessRequest和EndProcessRequest方法。在BeginProcessRequest内部通过调用RequestContext.RouteData获取controller控制器的名字,接下来ControllerFactory根据前面获取的控制器名称来创建controller实例。
接下来MvcHandler执行EndProcessRequest方法,controller实例调用Execute方法,内部通过另一个方法ExecuteCore执行核心操作。该方法中包含了很多的执行步骤,首先调用PossiblyLoadTempData(),控制器上下文ControllerContext判断当前请求是否IsChildAction来决定是否加载TempData数据,如果是ChildAction则不加载。
然后RouteData
获取当前Action的方法名,ControllerActionInvoker调用InvokeAction方法,在InvokeAction方法中执行我们在Controller中定义的方法,执行方法的前后后我们可以注册过滤器,以让我们在执行action的前后做一些自己想做的事情。所以第一步要做的是获取所有注册过滤器,这些过滤器信息获取后存在一个叫FilterInfo对象中,其中包含了AuthorizationFilters,ActionFilters,ResultFilters
,接下来调用方法GetParameterValues(controllerContext,
actionDescriptor)来获取action的参数。
调用InvokeActionMethodWithFi
调用InvokeActionResultWithFi
调用ViewResult
的FindView方法查找视图。内部通过ViewEngineCollection
ViewPath即为之前找到的视图路径,接着创建ViewEngineResult
最后释放视图,退出ResultExecute,这样视图的呈现就结束了。
执行OnResultExecuted。调用PossiblySaveTempData保存TempData数据。到这里Controller就执行完成了,退出ExecuteExecute方法,释放Cotroller对象。然后退出MvcHandler的执行,继续应用程序生命周期接下来的那些事件。
举个简单的例子比如数据库中存在两列firstName,lastName。我们获取两列的合并结果一般直接sql就可以了select firstName + lastName from tableName
不过利用DataTable中的表达式列也可以实现这样的效果,而且也很简单,看代码
DataTable table = new DataTable(); table.Columns.Add("firstName", typeof(string)); table.Columns.Add("lastName", typeof(string)); DataRow row1 = table.NewRow(); row1["firstName"] = "张"; row1["lastName"] = "三"; table.Rows.Add(row1); DataRow row2 = table.NewRow(); row2["firstName"] = "李"; row2["lastName"] = "四"; table.Rows.Add(row2); table.Columns.Add("fullName", typeof(string),"firstName+lastName");//这边创建一个前面两列相加的列 ddlCity.DataSource = table; ddlCity.DataTextField = "fullName";//这边直接写就有结果了 ddlCity.DataValueField = "firstName"; ddlCity.DataBind();
关键还有一个好处就是当其他列数据发生变化的时候,表达式列也会自动跟着变化,也挺好玩的
当对一个列表控件执行DataBind()会清空之前的所有数据项,因为很多时候如果加一个特殊项的话会选择在绑定完成后动态插入一条,就像下面这样
//下面前台代码 "ddlCity" runat="server">
//下面后台代码 Dictionary<<SPAN style="COLOR: #0000ff">string, string> citys = new Dictionary<<SPAN style="COLOR: #0000ff">string, string>(); citys.Add("北京", "1"); citys.Add("上海", "2"); ddlCity.DataSource = citys; ddlCity.DataTextField = "Key"; ddlCity.DataValueField = "Value"; ddlCity.DataBind(); ddlCity.Items.Insert(0, new ListItem("全部", "0"));
现在有了AppendDataBoundItems属性,表示是否追加绑定项,默认为false表示不追加,我们改为true就不需要像上面那样的写法了
//下面前台代码 "ddlCity" runat="server"> "全部" Value="0" Selected="True"> //下面后台代码 Dictionary<<SPAN style="COLOR: #0000ff">string, string> citys = new Dictionary<<SPAN style="COLOR: #0000ff">string, string>(); citys.Add("北京", "1"); citys.Add("上海", "2"); ddlCity.AppendDataBoundItems = true;//加入这个设置 ddlCity.DataSource = citys; ddlCity.DataTextField = "Key"; ddlCity.DataValueField = "Value"; ddlCity.DataBind();
而且如果多次调用DataBind()方法,也只会在后面追加数据而已,不管前面绑定过什么数据了,哈哈,不错吧
开发中经常碰到要处理很多数据的情况,然后希望在客户端展示当前的处理进度。之前有碰到客户端界面展示一个类似excel的报表,然后用户插入一批数据,然后点击保存后将所有数据一条条插入到数据库同时展示当前数据的处理结果。为了简便下面的代码已简单为主。
方式1:就是获取一条数据,然后发一个Ajax请求,等返回结果然后继续处理下一条,再发一个Ajax请求,循环往复,但是这样就需要多少的请求啊……
方式2:利用Response.Flush方法,第一次将全部的数据post到服务器,然后每次处理一条,利用Flush功能输出结果到客户端,这样就相当其实只有一个请求,然后浏览器一个接收数据,直到所有处理完成Response.Close下返回一个200的状态码
返现结果并不是我想象的那样,console.log只会在全部处理完毕以后再输出,奇怪了,firebug展示的响应结果是一直在不停向客户端输出的呀,好吧第一反应是jquery的success只会在返回200状态码后才会回调的,那Flush反悔的是什么状态码呢?好吧,哥不要你了,我用原生的ajax总行了吧,怎么说记得有一个onreadystatechage的方法,然后还有一个叫readyState的东东表示当前的状态,
确实有一个3表示数据传送中,表示接收部分数据,可是又郁闷了,此时因为响应及http头不全,这时通过responseBody和responseText获取部分数据会出现错误,得!看来不能用ajax了。好吧用iframe吧,直接写代码了
主页面Default.aspx提交