OpenXml Sdk 根据Word模板导出到word
一:OpenXml Sdk 简介
Open XML标准的简单介绍:Ecma Office Open XML(“Open XML”)是针对字处理文档、演示文稿和电子表格的国际化开放标准,可免费供多个应用程序在多个平台上实现。Microsoft Office(2007、2003、XP、2000)、OpenOffice Novell Edition、开源项目 Gnumeric、Neo-Office 2.1 和 PalmOS (Dataviz) 已经支持 Open XML。Corel 已经宣布在 WordPerfect 2007 中提供 Open XML 支持,全球的开发人员 正在使用 OpenXML 构建解决方案。
Open XML 的标准化工作是由 Ecma International 通过其技术委员会 45 (TC45) 执行的,来自 Apple、Barclays Capital、BP、The British Library、Essilor、Intel、Microsoft、NextPage、Novell、Statoil、Toshiba 和 United States Library of Congress 的代表参与了该项工作。该标准旨在提供现有 ISO 标准所无法提供的独特好处,其中包括能够实现从现有二进制格式向基于 XML 的格式的高保真移植。
二:OpenXml Sdk 安装
下载并安装OpenXMLSDKv2.msi和OpenXMLSDKTool.msi,下载地址:https://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=5124
官方SDK文档:
三:OpenXml Sdk 使用(新建项目)
打开vs新建项目OpenXmlWord,引用DocumentFormat.OpenXml.dll 和 WindowsBase.dll,如下如
新建word模板(word模板.docx)
四:OpenXml Sdk 使用(插入简单文本)
这里主要根据插入书签(BookMark)的方式来定位位置,打开word模板.docx分别在‘公司名称’和‘公司简介’中插入两个书签。
InsertSimpleText方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | /// <summary> /// /// </summary> /// <param name="filepPath"></param> /// <param name="Dictionary"></param> public static void InsertSimpleText( string filepPath, Dictionary< string , string > dictionary) { using (WordprocessingDocument wordprocessingDocument = WordprocessingDocument.Open(filepPath, true )) { List<BookmarkStart> allBookmarkStart = wordprocessingDocument.MainDocumentPart.RootElement.Descendants<BookmarkStart>().ToList(); foreach (KeyValuePair< string , string > keyValuePair in dictionary) { foreach (BookmarkStart bookmarkStart in allBookmarkStart) { if (bookmarkStart.Name.Value == keyValuePair.Key) { InsertIntoBookmark(bookmarkStart,keyValuePair.Value); break ; } } } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | /// <summary> /// 更换书签单一文本内容 /// </summary> /// <param name="bookmarkStart">书签</param> /// <param name="text">书签内容文本</param> private static void InsertIntoBookmark(BookmarkStart bookmarkStart, string text) { OpenXmlElement elem = bookmarkStart.NextSibling(); while (elem != null && !(elem is BookmarkEnd)) { OpenXmlElement nextElem = elem.NextSibling(); elem.Remove(); elem = nextElem; } bookmarkStart.Parent.InsertAfter<DocumentFormat.OpenXml.Wordprocessing.Run>( new DocumentFormat.OpenXml.Wordprocessing.Run( new DocumentFormat.OpenXml.Wordprocessing.Text(text)), bookmarkStart); } |
五:OpenXml Sdk 使用(插入图片)
根据步骤四中新建2个图片书签位置,具体代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | /// <summary> /// /// </summary> /// <param name="filepPath"></param> /// <param name="dictionary"></param> public static void InsertImage( string filepPath, Dictionary< string , string > dictionary, byte [] byteArrary= null ) { using (WordprocessingDocument wordprocessingDocument = WordprocessingDocument.Open(filepPath, true )) { List<BookmarkStart> allBookmarkStart = wordprocessingDocument.MainDocumentPart.RootElement.Descendants<BookmarkStart>().ToList(); { foreach (KeyValuePair< string , string > keyValuePair in dictionary) { foreach (BookmarkStart bookmarkStart in allBookmarkStart) { if (bookmarkStart.Name.Value == keyValuePair.Key) { byte [] imageByte = Convert.FromBase64String(keyValuePair.Value); MainDocumentPart mainPart = wordprocessingDocument.MainDocumentPart; ImagePart imagePart = mainPart.AddImagePart(ImagePartType.Jpeg); Stream stream = new MemoryStream(imageByte); if (byteArrary != null ) { stream = new MemoryStream(byteArrary); } imagePart.FeedData(stream); AddImageToBody(wordprocessingDocument, wordprocessingDocument.MainDocumentPart.GetIdOfPart(imagePart), bookmarkStart); break ; } } } } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | /// <summary> /// /// </summary> /// <param name="wordDoc"></param> /// <param name="relationshipId"></param> /// <param name="bookmarkStart"></param> private static void AddImageToBody(WordprocessingDocument wordDoc, string relationshipId, BookmarkStart bookmarkStart) { // Define the reference of the image. var element = new Drawing( new Inline( new Extent() { Cx = 4900000L, Cy = 3920000L }, // 调节图片大小 new EffectExtent() { LeftEdge = 0L, TopEdge = 0L, RightEdge = 0L, BottomEdge = 0L }, new DocProperties() { Id = (UInt32Value)1U, Name = "Picture 1" }, new DocumentFormat.OpenXml.Drawing.Wordprocessing.NonVisualGraphicFrameDrawingProperties( new GraphicFrameLocks() { NoChangeAspect = true }), new Graphic( new GraphicData( new DocumentFormat.OpenXml.Drawing.Pictures.Picture( new PIC.NonVisualPictureProperties( new PIC.NonVisualDrawingProperties() { Id = (UInt32Value)0U, Name = "New Bitmap Image.jpg" }, new DocumentFormat.OpenXml.Drawing.Pictures.NonVisualPictureDrawingProperties()), new DocumentFormat.OpenXml.Drawing.Pictures.BlipFill( new DocumentFormat.OpenXml.Drawing.Blip( new DocumentFormat.OpenXml.Drawing.BlipExtensionList( new DocumentFormat.OpenXml.Drawing.BlipExtension() { Uri = "{28A0092B-C50C-407E-A947-70E740481C1C}" }) ) { Embed = relationshipId, CompressionState = DocumentFormat.OpenXml.Drawing.BlipCompressionValues.Print }, new DocumentFormat.OpenXml.Drawing.Stretch( new DocumentFormat.OpenXml.Drawing.FillRectangle())), new PIC.ShapeProperties( new DocumentFormat.OpenXml.Drawing.Transform2D( new A.Offset() { X = 0L, Y = 0L }, new A.Extents() { Cx = 990000L, Cy = 792000L }), //与上面的对准 new A.PresetGeometry( new A.AdjustValueList() ) { Preset = A.ShapeTypeValues.Rectangle })) ) { Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" }) ) { DistanceFromTop = (UInt32Value)0U, DistanceFromBottom = (UInt32Value)0U, DistanceFromLeft = (UInt32Value)0U, DistanceFromRight = (UInt32Value)0U, EditId = "50D07946" }); //bookmarkStart.InsertAfterSelf(new DocumentFormat.OpenXml.Wordprocessing.Paragraph(new DocumentFormat.OpenXml.Wordprocessing.Run(element))); //bookmarkStart.Parent.InsertAfter<DocumentFormat.OpenXml.Wordprocessing.Run>(new DocumentFormat.OpenXml.Wordprocessing.Paragraph(new DocumentFormat.OpenXml.Wordprocessing.Run(element)), bookmarkStart); bookmarkStart.Parent.InsertAfter<DocumentFormat.OpenXml.Wordprocessing.Run>( new DocumentFormat.OpenXml.Wordprocessing.Run( new DocumentFormat.OpenXml.Wordprocessing.Run(element)), bookmarkStart); } |
注: 图片的长度和宽度都乘以9525之后导入到word里的图片显示为100%。
六:OpenXml Sdk 使用(根据表格写入数据)
首先给已有表格插入书签
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | /// <summary> /// /// </summary> /// <param name="filepPath"></param> /// <param name="configModel"></param> /// <param name="dataModelList"></param> public static void InsertTable( string filepPath, ConfigModel configModel, List<TableDataModel> dataModelList) { using (WordprocessingDocument wordprocessingDocument = WordprocessingDocument.Open(filepPath, true )) { Body body = wordprocessingDocument.MainDocumentPart.Document.Body; List<BookmarkStart> allBookmarkStart = wordprocessingDocument.MainDocumentPart.RootElement.Descendants<BookmarkStart>().ToList(); //通过索引获得table //var table = body.Elements<DocumentFormat.OpenXml.Wordprocessing.Table>().ElementAt(configModel.Index); //通过标签获得table BookmarkStart bookmarkStart = allBookmarkStart.Find(a => a.Name.Value == configModel.tableBookMark); if (bookmarkStart == null ) return ; var table = bookmarkStart.Parent.Parent.Parent.Parent; //List<DocumentFormat.OpenXml.Wordprocessing.TableRow> rowList = table.Elements<DocumentFormat.OpenXml.Wordprocessing.TableRow>().ToList(); //row = rowList[1].Clone() as DocumentFormat.OpenXml.Wordprocessing.TableRow; foreach (TableDataModel tableDataModel in dataModelList) { var row = table.Elements<DocumentFormat.OpenXml.Wordprocessing.TableRow>().ElementAt(configModel.StartRowIndex).Clone() as DocumentFormat.OpenXml.Wordprocessing.TableRow; var cells = row.Elements<DocumentFormat.OpenXml.Wordprocessing.TableCell>(); for ( int i = 0; i < cells.Count(); i++) { var cell = cells.ElementAt(i); //DocumentFormat.OpenXml.Wordprocessing.TableCell cellCreate = new DocumentFormat.OpenXml.Wordprocessing.TableCell(); //cellCreate.Append(new DocumentFormat.OpenXml.Wordprocessing.Paragraph(new DocumentFormat.OpenXml.Wordprocessing.Run(new DocumentFormat.OpenXml.Wordprocessing.Text(DateTime.Now.ToString())))); //row.Append(cell); //cell = cellCreate; DocumentFormat.OpenXml.Wordprocessing.Paragraph tmpPa = cell.Elements<DocumentFormat.OpenXml.Wordprocessing.Paragraph>().First(); var tmpRuns = tmpPa.Elements<DocumentFormat.OpenXml.Wordprocessing.Run>(); if (tmpRuns.Count() <= 0) { tmpPa.Remove(); tmpPa = new DocumentFormat.OpenXml.Wordprocessing.Paragraph( new DocumentFormat.OpenXml.Wordprocessing.Run( new DocumentFormat.OpenXml.Wordprocessing.Text( " " ))); //cell.RemoveAllChildren(); cell.Append(tmpPa); } var tmpRun = tmpPa.Elements<DocumentFormat.OpenXml.Wordprocessing.Run>().First(); var tmpText = tmpRun.Elements<DocumentFormat.OpenXml.Wordprocessing.Text>().First(); //获取属性值 Type type = tableDataModel.GetType(); string propertyKey = "Property" + (i + 1); System.Reflection.PropertyInfo propertyInfo = type.GetProperty(propertyKey); //获取指定名称的属性 object objValue = propertyInfo.GetValue(tableDataModel, null ); if (objValue != null ) { tmpText.Text = objValue.ToString(); } else { tmpText.Text = "-" ; } } //DocumentFormat.OpenXml.Wordprocessing.TableRow rowx = new DocumentFormat.OpenXml.Wordprocessing.TableRow(); //string[] rowArray = { "","","",""}; //foreach (string strCell in rowArray) //{ // DocumentFormat.OpenXml.Wordprocessing.TableCell cell = new DocumentFormat.OpenXml.Wordprocessing.TableCell(); // cell.Append(new DocumentFormat.OpenXml.Wordprocessing.Paragraph(new DocumentFormat.OpenXml.Wordprocessing.Run(new DocumentFormat.OpenXml.Wordprocessing.Text(strCell)))); // row.Append(cell); //} //table.Append(rowx); var lastRow = table.Elements<DocumentFormat.OpenXml.Wordprocessing.TableRow>().Last(); table.InsertAfter<DocumentFormat.OpenXml.Wordprocessing.TableRow>(row, lastRow); } //最后删除startIndex行 table.Elements<DocumentFormat.OpenXml.Wordprocessing.TableRow>().ElementAt(configModel.StartRowIndex).Remove(); } } |
最后源码下载地址:https://files.cnblogs.com/files/sunyj/OpenXmlWord.rar
相关资料网址:https://msdn.microsoft.com/en-us/library/bb497430(office.14).aspx
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?