当我接到领导安排“用word导出文档”的那一刻,我就想到有没有轻量级的开发组件,不用用户安装配套的office也可以使用,之前一直用Microsoft.Office.Interop.Word,虽然能达到效果,但是在使用中,如果用户安装多个office版本或安装了wps,有时就会报“无法将类型为 excel.applicationclass 的 com 强制转换为接口类型”,很烦人如果没有装office,就更麻烦了。
幸运的是,我发现了aspose word组件。
第一步,引用dll组件
第二步,建立模板
(1)通过书签,在模板中,插入|书签|输入书签的Name,点击“添加”,“确定”。
(2)通过域(懒得写了,摘录一图片):
显示书签:office按钮|Word选项|高级|在“显示文档内容”栏选中显示书签。
删除书签:光标放在书签上,点击工具“书签”,点击删除。
编辑域:选中域名,右击“编辑域”,弹出上图,直接输入名称,点确定。
插入已知DataTable:插入|表|选择两行N列:
第一行输入列的名称;
第二行第1列加入两个域:先添加关键字《TableStart:xx》xx:表名;再添加第1列的集合中对应的列名,如《ID》
第二行最后1列加入两个域:先添加集合中对应的列名,如《BZ》,再添加关键字《TableEnd:xx》。
插入图片
(1)通过书签,程序中利用DocumentBuilder的InsertNode事件,适用于多个图片或图片个数不确定的情况,使用时稍微有点复杂。
(2)通过域《Image:xx》xx:图片的name.程序中,指定name,利用DocumentBuilder的InsertImage事件,简单,只要指定url即可。
插入未知的DataTable
有可能table的列要用户自己指定,那么利用书签来完成。
第三步,程序开发
1、读取模板
String tmppath =Server.MapPath("~/UploadFiles/" + _id+"/template.dot");
Document doc = new Document(tmppath);
2、给书签赋值
if (doc.Range.Bookmarks["headertitle"]!=null)
{
Bookmarkmark = doc.Range.Bookmarks["headertitle"];
mark.Text = “Aspose Word组件开发”;//标题
}
3、给域赋值
DataTabledt = new DataTable();
dt.TableName=”xx”;
doc.MailMerge.ExecuteWithRegions(dt);//dt对应关键字中的xx
4、利用域读取图片
string picUrl = Server.MapPath("~/UploadFiles/"+ url);
double width = 100, height =100;
DocumentBuilder builder = new DocumentBuilder(doc);
builder.PageSetup.ClearFormatting();
builder.MoveToMergeField(fieldName);
Shape shape = builder.InsertImage(url); //插入图片:自动控制大小,并不遮挡后面的内容
shape.Width = width;
shape.Height =height;
shape.HorizontalAlignment= HorizontalAlignment.Center;
//Shapeshape = new Shape(doc, ShapeType.Image);
//shape.ImageData.SetImage(url);
//builder.InsertNode(shape); //用书签和用这个InsertNode都能实现插入图片,但是在word中,不会预留图片位置,而是将后面的内容覆盖掉了,下面介绍怎么才能不压后面的内容。
5、利用书签读取图片
DocumentBuilder builder = new DocumentBuilder(doc);
builder.MoveToBookmark("tablexst");//开始添加tableImage的地方
//builder.InsertBreak(Aspose.Words.BreakType.ParagraphBreak);
builder.StartTable();
//清除设置
builder.PageSetup.ClearFormatting();
builder.RowFormat.HeadingFormat= true;
builder.ParagraphFormat.Alignment = ParagraphAlignment.Center;
//生成Table
for (int i = 0; i< rowCount; i++)
{
for (int j = 0; j < colCount;j++)
{
AsposeCreateCell(builder, width, height);
}
builder.EndRow();
}
builder.EndTable();
//往建好的table中插入指定的图片,这样,就能预留出相应的位置。
shape.ImageData.SetImage(url);
shape.Width = width- 2;
shape.Height = height - 2;
shape.HorizontalAlignment = HorizontalAlignment.Center;
shape.VerticalAlignment= VerticalAlignment.Bottom;
//指定
builder.MoveToCell(7,r, c, 0);
builder.InsertNode(shape);
//最后一步
doc.Range.Bookmarks.Remove("tablexst"); //清掉标示
doc.MailMerge.DeleteFields();//删除所有未使用的空白
6.显示
var docStream = newSystem.IO.MemoryStream();
doc.Save(docStream, SaveFormat.Doc);
stringfamc = CommonHelper.GetString(dt.Rows[0]["FAMC"]);
returnbase.File(docStream.ToArray(),"application/msword", famc +".doc");
MVC中必须用base.File方法,且返回的是一个ActionResult,即JSON,所以当有错误返回时,也换成相应的JSON信息:
Try
{
//程序主体
}
catch (Exceptionex)
{
returnJson(ex.Message,JsonRequestBehavior.AllowGet);
}
前台:<iframe scrolling="auto" frameborder="0" src="' + url +'" width=100% height= 100%;"></iframe>
第四步,技术总结
1.Aspose Word在生成DataTable时,如果涉及到行合并或列合并时,请仔细斟酌,悟出他的原理。
2.直接在word中输入文字,DocumentBuilder.write或writeIn.
在这里也非常感谢博客园的BirchLee