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.msiOpenXMLSDKTool.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

posted @   青春岁月,无怨无悔  阅读(3140)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示