using Aspose.Words;
using Aspose.Words.Drawing;
using Newtonsoft.Json;
using System;
using System.IO;
using System.Linq;
namespace DocMarker
{
class Program
{
private static readonly string configFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.json");
private static readonly string backgroundImg = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "img", "bg.png");
private static readonly string headImg = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "img", "hd.png");
private static readonly string hiddenImg = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "img", "hid.png");
private static readonly HeaderFooterType[] headerTypes = { HeaderFooterType.HeaderPrimary, HeaderFooterType.HeaderFirst, HeaderFooterType.HeaderEven };
private static readonly HeaderFooterType[] footerTypes = { HeaderFooterType.FooterPrimary, HeaderFooterType.FooterFirst, HeaderFooterType.FooterEven };
private static readonly HeaderFooterType[] allTypes = { HeaderFooterType.HeaderPrimary, HeaderFooterType.HeaderFirst, HeaderFooterType.HeaderEven, HeaderFooterType.FooterPrimary, HeaderFooterType.FooterFirst, HeaderFooterType.FooterEven };
private static readonly int maxHidden = 99;
static void Main(string[] args)
{
License license = new License();
license.SetLicense(AsposeLicenseHelper.LicenseStream);
Config config;
if (File.Exists(configFile))
{
try
{
config = JsonConvert.DeserializeObject<Config>(File.ReadAllText(configFile));
}
catch
{
Console.WriteLine("配置文件不正确,请修改config.json文件");
Console.ReadKey();
return;
}
}
else
{
Console.WriteLine("未找到config.json文件,生成默认配置。");
config = new Config
{
file = @"C:\Users\Draco\Desktop\test.doc",
outputDir = ""
};
File.WriteAllText(configFile, JsonConvert.SerializeObject(config, Formatting.Indented));
}
Document doc = null;
try
{
if (File.Exists(config.file))
doc = HandleFile(config);
else if (Directory.Exists(config.file))
{
Console.WriteLine("遍历文件夹" + config.file);
foreach (var file in Directory.EnumerateFiles(config.file, "*.doc").Union(Directory.EnumerateFiles(config.file, "*.docx")))
{
config.file = file;
doc = HandleFile(config);
}
}
else
{
Console.WriteLine("文件路径不正确,请修改config.json中的file为Word文件路径或者文件夹路径");
}
}
catch (Exception ex)
{
Console.WriteLine("处理失败:" + ex.Message);
Console.WriteLine(ex.StackTrace);
}
Console.WriteLine("执行结束,按任意键退出...");
Console.ReadKey();
}
/// <summary>
/// 处理Word文件
/// </summary>
/// <param name="config"></param>
/// <returns></returns>
private static Document HandleFile(Config config)
{
Console.WriteLine("正在处理" + config.file);
var doc = new Document(config.file);
foreach (Section sec in doc.Sections)
{
var hasHeader = File.Exists(headImg);
var hasBackgorund = File.Exists(backgroundImg);
if (hasHeader || hasBackgorund)
{
removeHeaderFooter(sec, headerTypes);
var builder = new DocumentBuilder(doc);
if (hasHeader)
{
removeHeaderFooter(sec, footerTypes);
addHeaderFooter(builder, headImg, sec);
}
if (hasBackgorund)
addHeaderFooter(builder, backgroundImg, sec, true);
}
if (File.Exists(hiddenImg))
addWaterMark(hiddenImg, doc);
}
string dir;
if (string.IsNullOrWhiteSpace(config.outputDir))
{
dir = Path.Combine(Path.GetDirectoryName(config.file), Path.GetFileNameWithoutExtension(config.file) + "_wm" + Path.GetExtension(config.file));
}
else
{
dir = Path.Combine(config.outputDir, Path.GetFileName(config.file));
}
doc.Save(dir);
Console.WriteLine("文件另存为" + dir);
Console.WriteLine();
return doc;
}
/// <summary>
/// 添加隐藏水印
/// </summary>
/// <param name="img"></param>
/// <param name="doc"></param>
private static void addWaterMark(string img, Document doc)
{
var ps = doc.GetChildNodes(NodeType.Paragraph, true);
var r = new Random();
// 隐藏图片对象
Shape s = new Shape(doc, ShapeType.Image);
s.ImageData.SetImage(img);
s.Width = 1;
s.Height = 1;
s.WrapType = WrapType.Inline;
var hiddenCount = 0;
foreach (Paragraph p in ps)
{
if (p.ParentNode is HeaderFooter)
continue;
foreach (Run run in p.Runs)
{
// 大于一定长度或几率时随机截断文本插入隐藏图片副本
if (hiddenCount < maxHidden && run.Text.Length > 7 && r.NextDouble() >= 0.9)
{
var pos = r.Next(1, run.Text.Length);
Run after = (Run)run.Clone(true);
after.Text = run.Text.Substring(pos);
run.Text = run.Text.Substring(0, pos);
run.ParentNode.InsertAfter(after, run);
run.ParentNode.InsertAfter(s.Clone(true), run);
hiddenCount++;
}
}
}
}
/// <summary>
/// 添加页眉页脚
/// </summary>
/// <param name="img"></param>
/// <param name="sec"></param>
private static void addHeaderFooter(DocumentBuilder builder, string img, Section sec, bool isBackground = false)
{
foreach (var type in allTypes)
{
builder.MoveToHeaderFooter(type);
if (isBackground)
{
var shape = builder.InsertImage(img, RelativeHorizontalPosition.Margin, 0, RelativeVerticalPosition.Margin, 0,
sec.PageSetup.PageWidth - sec.PageSetup.LeftMargin - sec.PageSetup.RightMargin,
sec.PageSetup.PageHeight - sec.PageSetup.TopMargin - sec.PageSetup.BottomMargin, WrapType.None);
shape.BehindText = true;
}
else
{
var shape = builder.InsertImage(img);
shape.HorizontalAlignment = HorizontalAlignment.Left;
}
}
}
/// <summary>
/// 移除原有的页眉页脚
/// </summary>
/// <param name="sec"></param>
/// <param name="types"></param>
private static void removeHeaderFooter(Section sec, HeaderFooterType[] types)
{
foreach (var type in types)
{
var hf = sec.HeadersFooters[type];
if (hf != null)
hf.Remove();
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="NetOffice.Core.Net45" version="1.7.3.0" targetFramework="net452" />
<package id="NetOffice.Word.Net45" version="1.7.3.0" targetFramework="net452" />
<package id="Newtonsoft.Json" version="10.0.3" targetFramework="net452" />
</packages>
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.Windows;
namespace DocMarker
{
class Config
{
public string file { get; set; }
public string image { get; set; }
[JsonConverter(typeof(StringEnumConverter))]
public HorizontalAlignment imageAlign { get; set; }
private float _imageWidth = 0f;
public float imageWidth
{
get { return _imageWidth; }
set { _imageWidth = value; }
}
private float _imageHeight = 0f;
public float imageHeight
{
get { return _imageHeight; }
set { _imageHeight = value; }
}
public string footText { get; set; }
private float _footFontSize = 10.5f;
public float footFontSize
{
get { return _footFontSize; }
set { _footFontSize = value; }
}
public string outputDir { get; set; }
}
}
using Newtonsoft.Json;
using System;
using System.IO;
using System.Linq;
using System.Windows;
using word = NetOffice.WordApi;
namespace DocMarker
{
class Program
{
private static string configFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.json");
static void Main(string[] args)
{
Config config;
if (File.Exists(configFile))
{
config = JsonConvert.DeserializeObject<Config>(File.ReadAllText(configFile));
}
else
{
Console.WriteLine("未找到config.json文件,生成默认配置。");
config = new Config
{
file = @"C:\Users\Draco\Desktop\test111.doc",
image = @"E:\java\web\WebRoot\image\download\app-logo.png",
imageAlign = HorizontalAlignment.Right,
imageHeight = 32,
imageWidth = 32,
footFontSize = 10.5f,
footText = "中南出版传媒集团股份有限公司湖南教育出版社分公司贝壳网",
outputDir = ""
};
File.WriteAllText(configFile, JsonConvert.SerializeObject(config, Formatting.Indented));
}
word.Application app = null;
word.Document doc = null;
try
{
app = new word.Application();
app.DisplayAlerts = word.Enums.WdAlertLevel.wdAlertsNone;
app.Visible = false;
if (File.Exists(config.file))
doc = HandleFile(config, app);
else if (Directory.Exists(config.file))
{
Console.WriteLine("遍历文件夹" + config.file);
foreach (var file in Directory.EnumerateFiles(config.file, "*.doc").Union(Directory.EnumerateFiles(config.file, "*.docx")))
{
config.file = file;
doc = HandleFile(config, app);
}
}
else
{
Console.WriteLine("文件路径不正确,请修改config.json中的配置");
}
}
catch (Exception ex)
{
Console.WriteLine("处理失败:" + ex.Message);
}
finally
{
if (doc != null && !doc.IsCurrentlyDisposing && !doc.IsDisposed)
{
doc.Close();
doc.Dispose();
}
if (app != null && !app.IsCurrentlyDisposing && !app.IsDisposed)
{
app.Quit();
app.Dispose();
}
}
Console.WriteLine("执行结束,按任意键退出...");
Console.ReadKey();
}
private static word.Document HandleFile(Config config, word.Application app)
{
Console.WriteLine("正在处理" + config.file);
word.Document doc = app.Documents.Open(config.file);
foreach (var sec in doc.Sections)
{
if (File.Exists(config.image))
{
var headerRange = sec.Headers[word.Enums.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range;
headerRange.Select();
headerRange.Delete();
switch (config.imageAlign)
{
case HorizontalAlignment.Left:
headerRange.ParagraphFormat.Alignment = word.Enums.WdParagraphAlignment.wdAlignParagraphLeft;
break;
case HorizontalAlignment.Center:
headerRange.ParagraphFormat.Alignment = word.Enums.WdParagraphAlignment.wdAlignParagraphCenter;
break;
case HorizontalAlignment.Right:
headerRange.ParagraphFormat.Alignment = word.Enums.WdParagraphAlignment.wdAlignParagraphRight;
break;
case HorizontalAlignment.Stretch:
headerRange.ParagraphFormat.Alignment = word.Enums.WdParagraphAlignment.wdAlignParagraphJustify;
break;
default:
break;
}
var logo = headerRange.InlineShapes.AddPicture(config.image, false, true);
logo.Width = config.imageWidth;
logo.Height = config.imageHeight;
}
if (!string.IsNullOrWhiteSpace(config.footText))
{
word.Range footerRange = sec.Footers[word.Enums.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range;
footerRange.Select();
footerRange.Delete();
footerRange.Font.Size = config.footFontSize;
footerRange.Paragraphs.Alignment = word.Enums.WdParagraphAlignment.wdAlignParagraphCenter;
footerRange.Text = config.footText;
}
}
string dir;
if (string.IsNullOrWhiteSpace(config.outputDir))
{
dir = Path.Combine(Path.GetDirectoryName(config.file), Path.GetFileNameWithoutExtension(config.file) + "_wm" + Path.GetExtension(config.file));
}
else
{
dir = Path.Combine(config.outputDir, Path.GetFileName(config.file));
}
//doc.Protect(word.Enums.WdProtectionType.wdAllowOnlyReading, false, string.Empty, false, false);
doc.SaveAs(dir);
Console.WriteLine("文件另存为" + dir);
Console.WriteLine();
doc.Close();
doc.Dispose();
return doc;
}
}
}