/* Microshaoft 本文代码改自 http://powertools.codeplex.com/ http://powertools.codeplex.com/releases/view/74771#DownloadId=291022 文本水印、透明度、旋转 使用本文代码替代 Classes\WatermarkAccessor.cs 文件中的代码 Classes 目录下供 34个文件清单如下: Classes\BackgroundAccessor.cs Classes\ChartsheetAccessor.cs Classes\CommentAccessor.cs Classes\CommentMerger.cs Classes\ContentFormatAccessor.cs Classes\ContentStyleAccessor.cs Classes\CustomXmlAccessor.cs Classes\DigitalSignatureAccessor.cs Classes\DocumentBuilder.cs Classes\DocumentComparer.cs Classes\FooterAccessor.cs Classes\HeaderAccessor.cs Classes\HtmlConverter.cs Classes\IndexAccessor.cs Classes\ListItemRetriever.cs Classes\MarkupSimplifier.cs Classes\PictureAccessor.cs Classes\PowerToolsExtensions.cs Classes\PtOpenXmlDocument.cs Classes\PtOpenXmlUtil.cs Classes\PtUtil.cs Classes\ReferenceAdder.cs Classes\RevisionAccepter.cs Classes\SettingAccessor.cs Classes\SpreadsheetDocumentManager.cs Classes\SpreadSheetStyleAccessor.cs Classes\SpreadSheetTableAccessor.cs Classes\StyleAccessor.cs Classes\TextReplacer.cs Classes\ThemeAccessor.cs Classes\WatermarkAccessor.cs Classes\WordprocessingDocumentManager.cs Classes\WorksheetAccessor.cs %windir%\Microsoft.NET\Framework\v4.0.30319\csc.exe /out:OpenXmlWordAddWaterMark.exe *.cs /r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\WindowsBase.dll","C:\Program Files (x86)\Open XML SDK\V2.0\lib\DocumentFormat.OpenXml.dll" */ namespace Microshaoft { using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using OpenXmlPowerTools; class Class1 { static void Main(string[] args) { // "position:absolute;margin-left:0;margin-top:0;527.85pt;height:131.95pt;rotation:315;z-index:-251656192;mso-position-horizontal:center;mso-position-horizontal-relative:margin;mso-position-vertical:center;mso-position-vertical-relative:margin"; WmlDocument wmlDoc = new WmlDocument(@"d:\a.docx"); OpenXmlPowerToolsDocument doc = WatermarkAccessor.InsertWatermark ( wmlDoc , "测试123abcABC@Microshaoft" , 527 , 200 , 110 , "楷体" , 10 , "red" , 10 ); doc.SaveAs(@"d:\a1.docx"); } } } namespace OpenXmlPowerTools { /*************************************************************************** Copyright (c) Microsoft Corporation 2011. This code is licensed using the Microsoft Public License (Ms-PL). The text of the license can be found here: http://www.microsoft.com/resources/sharedsource/licensingbasics/publiclicense.mspx ***************************************************************************/ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Xml.Linq; using DocumentFormat.OpenXml.Packaging; using System.Drawing; /// <summary> /// Provides access to watermark operations /// </summary> public class WatermarkAccessor { private static XNamespace ns; private static XNamespace officens; private static XNamespace vmlns; private static XNamespace relationshipsns; private static string diagonalWatermarkStyle = "position:absolute;margin-left:0;margin-top:0;527.85pt;height:131.95pt;rotation:315;z-index:-251656192;mso-position-horizontal:center;mso-position-horizontal-relative:margin;mso-position-vertical:center;mso-position-vertical-relative:margin"; private static string fontFamilySizeStyle = "font-family:"Calibri";font-size:1pt"; private static string fillColor = "black"; private static int opacity = 50; //private static string defaultWatermarkStyle = "position:absolute;margin-left:0;margin-top:0;468pt;height:117pt;z-index:-251652096;mso-position-horizontal:center;mso-position-horizontal-relative:margin;mso-position-vertical:center;mso-position-vertical-relative:margin"; static WatermarkAccessor() { ns = "http://schemas.openxmlformats.org/wordprocessingml/2006/main"; officens = "urn:schemas-microsoft-com:office:office"; vmlns = "urn:schemas-microsoft-com:vml"; relationshipsns = "http://schemas.openxmlformats.org/officeDocument/2006/relationships"; } /// <summary> /// Inserts a watermark text inside a document /// </summary> /// <param name="watermarkText">text to show in the watermark</param> /// <param name="diagonalOrientation">specify that the text orientation will be in a diagonal way</param> public static OpenXmlPowerToolsDocument InsertWatermark ( WmlDocument doc , string watermarkText , int width , int height , int rotation , string fontFamilyName , int fontSize , string fillColor , int opacityPercent //, bool diagonalOrientation ) { // "position:absolute;margin-left:0;margin-top:0;527.85pt;height:131.95pt;rotation:315;z-index:-251656192;mso-position-horizontal:center;mso-position-horizontal-relative:margin;mso-position-vertical:center;mso-position-vertical-relative:margin"; diagonalWatermarkStyle = string.Format ( @" position:absolute; margin-left:0; margin-top:0; {0}pt; height:{1}pt; rotation:{2}; z-index:-251656192; mso-position-horizontal:center; mso-position-horizontal-relative:margin; mso-position-vertical:center; mso-position-vertical-relative:margin " , width , height , rotation ); fontFamilySizeStyle = string.Format ( @" font-family:"{0}" ; font-size:{1}pt " , fontFamilyName , fontSize ); opacity = opacityPercent; //diagonalWatermarkStyle="position:absolute;margin-left:0;margin-top:0;527.85pt;height:131.95pt;rotation:315;z-index:-251656192;mso-position-horizontal:center;mso-position-horizontal-relative:margin;mso-position-vertical:center;mso-position-vertical-relative:margin"; //defaultWatermarkStyle = "position:absolute;margin-left:0;margin-top:0;468pt; height:117pt; z-index:-251652096;mso-position-horizontal:center;mso-position-horizontal-relative:margin;mso-position-vertical:center;mso-position-vertical-relative:margin"; using (OpenXmlMemoryStreamDocument streamDoc = new OpenXmlMemoryStreamDocument(doc)) { using (WordprocessingDocument document = streamDoc.GetWordprocessingDocument()) { Collection<XDocument> headers = new Collection<XDocument>(); if (HeaderAccessor.GetHeaderReference(document, HeaderType.First, 0) == null) headers.Add(HeaderAccessor.AddNewHeader(document, HeaderType.First)); else headers.Add(HeaderAccessor.GetHeader(document, HeaderType.First, 0)); if (HeaderAccessor.GetHeaderReference(document, HeaderType.Even, 0) == null) headers.Add(HeaderAccessor.AddNewHeader(document, HeaderType.Even)); else headers.Add(HeaderAccessor.GetHeader(document, HeaderType.Even, 0)); if (HeaderAccessor.GetHeaderReference(document, HeaderType.Default, 0) == null) headers.Add(HeaderAccessor.AddNewHeader(document, HeaderType.Default)); else headers.Add(HeaderAccessor.GetHeader(document, HeaderType.Default, 0)); foreach (XDocument header in headers) { var runElement = header.Descendants(ns + "r").FirstOrDefault(); if (runElement == null) { header.Root.Add( new XElement(ns + "sdt", new XElement(ns + "sdtContent", new XElement(ns + "p", new XElement(ns + "pPr", new XElement(ns + "pStyle", new XAttribute(ns + "val", "Header") ) ), runElement = new XElement(ns + "r") ) ) ) ); } runElement.AddBeforeSelf(CreateWatermarkVml(watermarkText)); } HeaderAccessor.GetHeaderPart(document, HeaderType.First, 0).PutXDocument(); HeaderAccessor.GetHeaderPart(document, HeaderType.Even, 0).PutXDocument(); HeaderAccessor.GetHeaderPart(document, HeaderType.Default, 0).PutXDocument(); } return streamDoc.GetModifiedDocument(); } } /// <summary> /// Creates the markup for watermark displaying /// </summary> /// <param name="watermarkText">Text to include in markup</param> /// <param name="diagonalOrientation">Orientation of text</param> /// <returns>Watermark markup</returns> private static XElement CreateWatermarkVml(string watermarkText) { return new XElement(ns + "r", new XElement(ns + "pict", new XElement(vmlns + "shapetype", new XAttribute("id", "_x0000_t136"), new XAttribute("coordsize", "21600,21600"), new XAttribute(officens + "spt", "136"), new XAttribute("adj", "10800"), new XAttribute("path", "m@7,l@8,m@5,21600l@6,21600e"), new XElement(vmlns + "formulas", new XElement(vmlns + "f", new XAttribute("eqn", "sum #0 0 10800") ), new XElement(vmlns + "f", new XAttribute("eqn", "prod #0 2 1") ), new XElement(vmlns + "f", new XAttribute("eqn", "sum 21600 0 @1") ), new XElement(vmlns + "f", new XAttribute("eqn", "sum 0 0 @2") ), new XElement(vmlns + "f", new XAttribute("eqn", "sum 21600 0 @3") ), new XElement(vmlns + "f", new XAttribute("eqn", "if @0 @3 0") ), new XElement(vmlns + "f", new XAttribute("eqn", "if @0 21600 @1") ), new XElement(vmlns + "f", new XAttribute("eqn", "if @0 0 @2") ), new XElement(vmlns + "f", new XAttribute("eqn", "if @0 @4 21600") ), new XElement(vmlns + "f", new XAttribute("eqn", "mid @5 @6") ), new XElement(vmlns + "f", new XAttribute("eqn", "mid @8 @5") ), new XElement(vmlns + "f", new XAttribute("eqn", "mid @7 @8") ), new XElement(vmlns + "f", new XAttribute("eqn", "mid @6 @7") ), new XElement(vmlns + "f", new XAttribute("eqn", "sum @6 0 @5") ) ), new XElement(vmlns + "path", new XAttribute("textpathok", "t"), new XAttribute(officens + "connecttype", "custom"), new XAttribute(officens + "connectlocs", "@9,0;@10,10800;@11,21600;@12,10800"), new XAttribute(officens + "connectangles", "270,180,90,0") ), new XElement(vmlns + "textpath", new XAttribute("on", "t"), new XAttribute("fitshape", "t") ), new XElement(vmlns + "handles", new XElement(vmlns + "h", new XAttribute("position", "#0,bottomRight"), new XAttribute("xrange", "6629,14971") ) ), new XElement(officens + "lock", new XAttribute(vmlns + "ext", "edit"), new XAttribute("text", "t"), new XAttribute("shapetype", "t") ) ), new XElement(vmlns + "shape", new XAttribute("id", "PowerPlusWaterMarkObject98078923"), new XAttribute(officens + "spid", "_x0000_s2055"), new XAttribute("type", "#_x0000_t136"), //new XAttribute("style", diagonalOrientation ? diagonalWatermarkStyle : defaultWatermarkStyle), new XAttribute("style", diagonalWatermarkStyle), new XAttribute(officens + "allowincell", "f"), new XAttribute("fillcolor", fillColor), new XAttribute("stroked", "f"), new XElement(vmlns + "fill", new XAttribute("opacity", opacity/100.0) ), new XElement(vmlns + "textpath", new XAttribute("style", fontFamilySizeStyle), new XAttribute("string", watermarkText) ) ) ) ); } /// <summary> /// Gets the text related to watermark from a document /// </summary> /// <returns>Watermark text</returns> public static string GetWatermarkText(WmlDocument doc) { IEnumerable<XElement> watermarkDescription = GetWatermark(doc); if (watermarkDescription != null) return watermarkDescription .Descendants(vmlns + "shape") .Descendants(vmlns + "textpath") .First() .Attribute("string") .Value; else return string.Empty; } /// <summary> /// Gets the document structure related to watermark description /// </summary> /// <returns>Document structure related to watermark description</returns> public static IEnumerable<XElement> GetWatermark(WmlDocument doc) { using (OpenXmlMemoryStreamDocument streamDoc = new OpenXmlMemoryStreamDocument(doc)) using (WordprocessingDocument document = streamDoc.GetWordprocessingDocument()) { // to get the watermark text, we have to look inside the document // get the default header reference and get the header reference id part XElement defaultHeaderReference = HeaderAccessor.GetHeaderReference(document, HeaderType.Default, 0); if (defaultHeaderReference != null) { string headerReferenceId = defaultHeaderReference.Attribute(relationshipsns + "id").Value; OpenXmlPart headerPart = document.MainDocumentPart.GetPartById(headerReferenceId); if (headerPart != null) { XDocument headerPartXml = headerPart.GetXDocument(); return headerPartXml.Descendants(ns + "pict"); } } return null; } } } }