大家好,欢迎来到IT知识分享网。
OpenXML概述
项目中经常需要操作word,之前的方式是采用COM接口,这个接口很不稳定,经常报错。现在开始采用OpenXML。OpenXML(OOXML)是微软在Office 2007中提出的一种新的文档格式,Office 2007中的Word、Excel、PowerPoint默认均采用OpenXML格式 。
OpenXml相对于用MS提供的COM组件来生成WORD,有如下优势:
1.相对于MS 的COM组件,因为版本带来的不兼容问题,及各种会生成WORD半途会崩溃的问题.
2.对比填满一张30多页的WORD来说(包含图,表等),用COM组件来生成会占用20秒,Openxml1秒.
3.MS Word软件太贵了,你的客户装的是开源WORD,如LibreOffice,OpenOffice.这样你就只能用Openxml生成的WORD文档,各种支持MS Word都能打开,避免客户机器上安装MS Word.
4.代码简单。用OpenXML开发word简直太方便了!!!
要做OpenXML的开发,需要了解OpenXML的基本结构。
Open XML SDK 2.0 tool
因为OpenXML的结构比较复杂,开始开发时往往不好入门,摸不清其结构。微软很贴心的提供了一个工具,Open XML SDK Productivity Tool for Microsoft Office。
下载地址 百度云:OpenXMLSDKTool 提取码: u6q8 OpenXMLSDK 提取码: k873
这个工具可以打开任意一个docx的文档,然后Reflect Code,得到整个文档代码,之后怎么操作直接看代码就好了,真是太方便了。
另外这个工具也提供了文档,不清楚的可以查一下文档。
代码示例
我参考上面的工具,写了一个简单的操作word的帮助类。
using System.Collections.Generic; using System.IO; using DocumentFormat.OpenXml; using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Wordprocessing; using AA = DocumentFormat.OpenXml.Drawing; using DW = DocumentFormat.OpenXml.Drawing.Wordprocessing; using PIC = DocumentFormat.OpenXml.Drawing.Pictures; namespace Wisdombud.Office { public static class OpenXmlUtil { /// <summary> /// 按书签替换图片 /// </summary> /// <param name="filePath"></param> /// <param name="picPath"></param> /// <param name="bm"></param> /// <param name="x">宽度厘米</param> /// <param name="y">高度厘米</param> /// <param name="type"></param> public static void ReplaceBMPicture(string filePath, string picPath, string bm) { RemoveBookMarkContent(filePath, bm); InsertBMPicture(filePath, picPath, bm); } /// <summary> /// 按书签替换图片 /// </summary> /// <param name="filePath"></param> /// <param name="picPath"></param> /// <param name="bm"></param> /// <param name="x">宽度厘米</param> /// <param name="y">高度厘米</param> /// <param name="type"></param> public static void ReplaceBMPicture(string filePath, string picPath, string bm, long x, ImagePartType type) { RemoveBookMarkContent(filePath, bm); InsertBMPicture(filePath, picPath, bm, x, type); } /// <summary> /// 按书签替换图片 /// </summary> /// <param name="filePath"></param> /// <param name="picPath"></param> /// <param name="bm"></param> /// <param name="x">宽度厘米</param> /// <param name="y">高度厘米</param> /// <param name="type"></param> public static void ReplaceBMPicture(string filePath, string picPath, string bm, long x, long y, ImagePartType type) { RemoveBookMarkContent(filePath, bm); InsertBMPicture(filePath, picPath, bm, x, y, type); } /// <summary> /// 按书签插入图片 /// </summary> /// <param name="filePath"></param> /// <param name="picPath"></param> /// <param name="bm"></param> /// <param name="x">宽度厘米</param> /// <param name="y">高度厘米</param> /// <param name="type"></param> public static void InsertBMPicture(string filePath, string picPath, string bm, long x, ImagePartType type) { long y = 0; using (System.Drawing.Bitmap objPic = new System.Drawing.Bitmap(picPath)) { y = (x * objPic.Height) / objPic.Width; } InsertBMPicture(filePath, picPath, bm, x, y, type); } /// <summary> /// 按书签插入图片 /// </summary> /// <param name="filePath"></param> /// <param name="picPath"></param> /// <param name="bm"></param> /// <param name="x">宽度厘米</param> /// <param name="y">高度厘米</param> /// <param name="type"></param> public static void InsertBMPicture(string filePath, string picPath, string bm, long x, long y, ImagePartType type) { using (WordprocessingDocument doc = WordprocessingDocument.Open(filePath, true)) { MainDocumentPart mainPart = doc.MainDocumentPart; BookmarkStart bmStart = findBookMarkStart(doc, bm); if (bmStart == null) { return; } ImagePart imagePart = mainPart.AddImagePart(type); using (FileStream stream = new FileStream(picPath, FileMode.Open)) { imagePart.FeedData(stream); } long cx = 360000L * x;//360000L = 1厘米 long cy = 360000L * y; Run r = AddImageToBody(doc, mainPart.GetIdOfPart(imagePart), cx, cy); bmStart.Parent.InsertAfter<Run>(r, bmStart); mainPart.Document.Save(); } } /// <summary> /// 按书签插入图片。默认15厘米,JPG /// </summary> /// <param name="filePath"></param> /// <param name="picPath"></param> /// <param name="bm"></param> public static void InsertBMPicture(string filePath, string picPath, string bm) { InsertBMPicture(filePath, picPath, bm, 15, 15, ImagePartType.Jpeg); } /// <summary> /// 查找书签 /// </summary> /// <param name="doc"></param> /// <param name="bmName"></param> /// <returns></returns> private static BookmarkStart findBookMarkStart(WordprocessingDocument doc, string bmName) { foreach (var footer in doc.MainDocumentPart.FooterParts) { foreach (var inst in footer.Footer.Descendants<BookmarkStart>()) { if (inst.Name == bmName) { return inst; } } } foreach (var header in doc.MainDocumentPart.HeaderParts) { foreach (var inst in header.Header.Descendants<BookmarkStart>()) { if (inst.Name == bmName) { return inst; } } } foreach (var inst in doc.MainDocumentPart.RootElement.Descendants<BookmarkStart>()) { if (inst is BookmarkStart) { if (inst.Name == bmName) { return inst; } } } return null; } /// <summary> /// 查找书签 /// </summary> /// <param name="doc"></param> /// <param name="bmName"></param> /// <returns></returns> private static List<BookmarkStart> findAllBookMarkStart(WordprocessingDocument doc) { List<BookmarkStart> ret = new List<BookmarkStart>(); foreach (var footer in doc.MainDocumentPart.FooterParts) { ret.AddRange(footer.Footer.Descendants<BookmarkStart>()); } foreach (var header in doc.MainDocumentPart.HeaderParts) { ret.AddRange(header.Header.Descendants<BookmarkStart>()); } ret.AddRange(doc.MainDocumentPart.RootElement.Descendants<BookmarkStart>()); return ret; } /// <summary> /// 查找书签 /// </summary> /// <param name="doc"></param> /// <param name="bmName"></param> /// <returns></returns> private static List<BookmarkEnd> findAllBookMarkEnd(WordprocessingDocument doc) { List<BookmarkEnd> ret = new List<BookmarkEnd>(); foreach (var footer in doc.MainDocumentPart.FooterParts) { ret.AddRange(footer.Footer.Descendants<BookmarkEnd>()); } foreach (var header in doc.MainDocumentPart.HeaderParts) { ret.AddRange(header.Header.Descendants<BookmarkEnd>()); } ret.AddRange(doc.MainDocumentPart.RootElement.Descendants<BookmarkEnd>()); return ret; } /// <summary> /// 查找书签END /// </summary> /// <param name="doc"></param> /// <param name="bmName"></param> /// <returns></returns> private static BookmarkEnd findBookMarkEnd(WordprocessingDocument doc, string id) { foreach (var footer in doc.MainDocumentPart.FooterParts) { foreach (var inst in footer.Footer.Descendants<BookmarkEnd>()) { if (inst.Id == id) { return inst; } } } foreach (var header in doc.MainDocumentPart.HeaderParts) { foreach (var inst in header.Header.Descendants<BookmarkEnd>()) { if (inst.Id == id) { return inst; } } } foreach (var inst in doc.MainDocumentPart.RootElement.Descendants<BookmarkEnd>()) { if (inst.Id == id) { return inst; } } return null; } private static Run AddImageToBody(WordprocessingDocument wordDoc, string relationshipId, long cx, long cy) { return new Run(new Drawing( new DW.Inline( new DW.Extent() { Cx = cx, Cy = cy }, new DW.EffectExtent() { LeftEdge = 0L, TopEdge = 0L, RightEdge = 0L, BottomEdge = 0L }, new DW.DocProperties() { Id = (UInt32Value)1U, Name = "Picture 1" }, new DW.NonVisualGraphicFrameDrawingProperties( new AA.GraphicFrameLocks() { NoChangeAspect = true }), new AA.Graphic( new AA.GraphicData( new PIC.Picture( new PIC.NonVisualPictureProperties( new PIC.NonVisualDrawingProperties() { Id = (UInt32Value)0U, Name = "New Bitmap Image.jpg" }, new PIC.NonVisualPictureDrawingProperties()), new PIC.BlipFill( new AA.Blip( new AA.BlipExtensionList( new AA.BlipExtension() { Uri = "{28A0092B-C50C-407E-A947-70E740481C1C}" }) ) { Embed = relationshipId, CompressionState = AA.BlipCompressionValues.Print }, new AA.Stretch( new AA.FillRectangle())), new PIC.ShapeProperties( new AA.Transform2D( new AA.Offset() { X = 0L, Y = 0L }, new AA.Extents() { Cx = 990000L, Cy = 792000L }), new AA.PresetGeometry( new AA.AdjustValueList() ) { Preset = AA.ShapeTypeValues.Rectangle })) ) { Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" }) ) { DistanceFromTop = (UInt32Value)0U, DistanceFromBottom = (UInt32Value)0U, DistanceFromLeft = (UInt32Value)0U, DistanceFromRight = (UInt32Value)0U, EditId = "50D07946" })); // Append the reference to body, the element should be in a Run. // wordDoc.MainDocumentPart.Document.Body.AppendChild(new Paragraph(new Run(element))); } public static void DeleteRange(string filePath, string stringStart, string stringStop, int way) { using (WordprocessingDocument doc = WordprocessingDocument.Open(filePath, true)) { List<OpenXmlElement> list = RangeFind(doc, stringStart, stringStop, way); foreach (var inst in list) { inst.Remove(); } } } /// <summary> /// 1 标记1结束到标记2开始;2 标记1结束到标记2结束;3 标记1开始到标记2结束; 4 标记1开始到标记2开始; /// trimhuiche 如果为true,则考虑回车;否则不考虑回车。 /// chzhao@wisdombud.com /// </summary> /// <param name="stringStart"></param> /// <param name="stringStop"></param> /// <param name="way"></param> public static List<OpenXmlElement> RangeFind(WordprocessingDocument doc, string stringStart, string stringStop, int way) { List<OpenXmlElement> ret = new List<OpenXmlElement>(); bool add = false; foreach (var inst in doc.MainDocumentPart.Document.Body.Elements()) { if (way == 1) { if (inst.InnerText.Contains(stringStop)) { add = false; } if (add) { ret.Add(inst.CloneNode(true)); } if (inst.InnerText == stringStart) { add = true; } } else if (way == 2) { if (add) { ret.Add(inst.CloneNode(true)); } if (inst.InnerText == stringStart) { add = true; } if (inst.InnerText.Contains(stringStop)) { add = false; } } else if (way == 3) { if (inst.InnerText == stringStart) { add = true; } if (add) { ret.Add(inst.CloneNode(true)); } if (inst.InnerText.Contains(stringStop)) { add = false; } } else if (way == 4) { if (inst.InnerText == stringStart) { add = true; } if (inst.InnerText.Contains(stringStop)) { add = false; } if (add) { ret.Add(inst.CloneNode(true)); } } } return ret; } /// <summary> /// 修改书签 /// </summary> /// <param name="filePath">word文档</param> /// <param name="bmName">书签名字</param> /// <param name="text">替换的文本</param> public static void ModifyBM(string filePath, string bmName, string text) { using (WordprocessingDocument doc = WordprocessingDocument.Open(filePath, true)) { BookmarkStart bmStart = findBookMarkStart(doc, bmName); Run bookmarkText = bmStart.NextSibling<Run>(); if (bookmarkText != null) { Text t = bookmarkText.GetFirstChild<Text>(); if (t != null) { t.Text = text; } } } } /// <summary> /// 删除书签内容 /// </summary> /// <param name="bookmark"></param> public static void RemoveBookMarkContent(string filePath, string bmName) { using (WordprocessingDocument doc = WordprocessingDocument.Open(filePath, true)) { BookmarkStart bmStart = findBookMarkStart(doc, bmName); BookmarkEnd bmEnd = findBookMarkEnd(doc, bmStart.Id); while (true) { var run = bmStart.NextSibling(); if (run == null) { break; } if (run is BookmarkEnd && (BookmarkEnd)run == bmEnd) { break; } run.Remove(); } } } /// <summary> /// 重命名书签,在书签前面加前缀 /// </summary> /// <param name="filePath"></param> /// <param name="prefix">前缀</param> public static void RenameBookMark(string filePath, string prefix) { using (WordprocessingDocument doc = WordprocessingDocument.Open(filePath, true)) { foreach (var inst in findAllBookMarkStart(doc)) { inst.Name = prefix + inst.Name; } } } /// <summary> /// 重命名书签 /// </summary> /// <param name="filePath"></param> /// <param name="oldName"></param> /// <param name="newName"></param> public static void RenameBookMark(string filePath, string oldName, string newName) { using (WordprocessingDocument doc = WordprocessingDocument.Open(filePath, true)) { var bm = findBookMarkStart(doc, oldName); bm.Name = newName; } } /// <summary> /// 删除书签 /// </summary> /// <param name="bookmark"></param> public static void RemoveBookMark(string filePath, string bmName) { using (WordprocessingDocument doc = WordprocessingDocument.Open(filePath, true)) { var bmStart = findBookMarkStart(doc, bmName); if (bmStart == null) { return; } var bmEnd = findBookMarkEnd(doc, bmStart.Id); bmStart.Remove(); bmEnd.Remove(); } } /// <summary> /// 合并文档 /// </summary> /// <param name="finalFile"></param> /// <param name="files"></param> public static void Combine(string finalFile, List<string> files) { if (files.Count < 2) { return; } File.Copy(files[0], finalFile, true); using (WordprocessingDocument doc = WordprocessingDocument.Open(finalFile, true)) { Body b = doc.MainDocumentPart.Document.Body; for (int i = 1; i < files.Count; i++) { using (WordprocessingDocument doc1 = WordprocessingDocument.Open(files[i], true)) { foreach (var inst in doc1.MainDocumentPart.Document.Body.Elements()) { b.Append(inst.CloneNode(true)); } } } } } } }
原文地址:【转】【OpenXML】OpenXML操作word
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/31579.html