/*
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;width: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;width: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;width: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;width: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;
width:{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;width: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;width: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;
}
}
}
}