我正在尝试获取现有文档,如果标题不存在,请创建一个,然后在标题中添加一个水印,上面对角地写着“DRAFT”。我按照一个例子发布了 here如果标题已经存在,我已经将代码添加到添加水印的位置。
当前的问题是当我添加一个新的标题,添加对文档的引用,然后将水印添加到标题时,文档损坏并且无法再在 Word 2010 中打开。
为了测试,我一直在执行以下操作:从 word 本身创建一个新的 word 文档,在页面的主要部分中包含文本“TestDoc”。将文件另存为“TestDoc.docx”并关闭文件。然后我从 Visual Studio 运行应用程序。下面的代码总是会使其损坏。如果我向文件中添加一个没有文本的标题,然后点击保存,水印将正确显示。
这是我目前所拥有的:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Vml;
using DocumentFormat.OpenXml.Vml.Office;
using DocumentFormat.OpenXml.Vml.Wordprocessing;
using DocumentFormat.OpenXml.Wordprocessing;
using HorizontalAnchorValues = DocumentFormat.OpenXml.Vml.Wordprocessing.HorizontalAnchorValues;
using Lock = DocumentFormat.OpenXml.Vml.Office.Lock;
using VerticalAnchorValues = DocumentFormat.OpenXml.Vml.Wordprocessing.VerticalAnchorValues;
namespace DocumentWatermarkTest
{
class Program
{
static void Main(string[] args)
{
var doc = WordprocessingDocument.Open(@"C:\Users\loggedinuser\Desktop\TestDoc.docx", true);
AddWatermark(doc);
doc.MainDocumentPart.Document.Save();
}
static Header MakeHeader()
{
var header = new Header();
var paragraph = new Paragraph();
var run = new Run();
var text = new Text();
text.Text = "";
run.Append(text);
paragraph.Append(run);
header.Append(paragraph);
return header;
}
static void AddWatermark(WordprocessingDocument doc)
{
if (doc.MainDocumentPart.HeaderParts.Count() == 0)
{
doc.MainDocumentPart.DeleteParts(doc.MainDocumentPart.HeaderParts);
var newHeaderPart = doc.MainDocumentPart.AddNewPart<HeaderPart>();
var rId = doc.MainDocumentPart.GetIdOfPart(newHeaderPart);
var headerRef = new HeaderReference();
headerRef.Id = rId;
var sectionProps = doc.MainDocumentPart.Document.Body.Elements<SectionProperties>().LastOrDefault();
if (sectionProps == null)
{
sectionProps = new SectionProperties();
doc.MainDocumentPart.Document.Body.Append(sectionProps);
}
sectionProps.RemoveAllChildren<HeaderReference>();
sectionProps.Append(headerRef);
newHeaderPart.Header = MakeHeader();
newHeaderPart.Header.Save();
}
foreach (HeaderPart headerPart in doc.MainDocumentPart.HeaderParts)
{
var sdtBlock1 = new SdtBlock();
var sdtProperties1 = new SdtProperties();
var sdtId1 = new SdtId() { Val = 87908844 };
var sdtContentDocPartObject1 = new DocPartObjectSdt();
var docPartGallery1 = new DocPartGallery() { Val = "Watermarks" };
var docPartUnique1 = new DocPartUnique();
sdtContentDocPartObject1.Append(docPartGallery1);
sdtContentDocPartObject1.Append(docPartUnique1);
sdtProperties1.Append(sdtId1);
sdtProperties1.Append(sdtContentDocPartObject1);
var sdtContentBlock1 = new SdtContentBlock();
var paragraph2 = new Paragraph()
{
RsidParagraphAddition = "00656E18",
RsidRunAdditionDefault = "00656E18"
};
var paragraphProperties2 = new ParagraphProperties();
var paragraphStyleId2 = new ParagraphStyleId() { Val = "Header" };
paragraphProperties2.Append(paragraphStyleId2);
var run1 = new Run();
var runProperties1 = new RunProperties();
var noProof1 = new NoProof();
var languages1 = new Languages() { EastAsia = "zh-TW" };
runProperties1.Append(noProof1);
runProperties1.Append(languages1);
var picture1 = new Picture();
var shapetype1 = new Shapetype()
{
Id = "_x0000_t136",
CoordinateSize = "21600,21600",
OptionalNumber = 136,
Adjustment = "10800",
EdgePath = "m@7,l@8,m@5,21600l@6,21600e"
};
var formulas1 = new Formulas();
var formula1 = new Formula() { Equation = "sum #0 0 10800" };
var formula2 = new Formula() { Equation = "prod #0 2 1" };
var formula3 = new Formula() { Equation = "sum 21600 0 @1" };
var formula4 = new Formula() { Equation = "sum 0 0 @2" };
var formula5 = new Formula() { Equation = "sum 21600 0 @3" };
var formula6 = new Formula() { Equation = "if @0 @3 0" };
var formula7 = new Formula() { Equation = "if @0 21600 @1" };
var formula8 = new Formula() { Equation = "if @0 0 @2" };
var formula9 = new Formula() { Equation = "if @0 @4 21600" };
var formula10 = new Formula() { Equation = "mid @5 @6" };
var formula11 = new Formula() { Equation = "mid @8 @5" };
var formula12 = new Formula() { Equation = "mid @7 @8" };
var formula13 = new Formula() { Equation = "mid @6 @7" };
var formula14 = new Formula() { Equation = "sum @6 0 @5" };
formulas1.Append(formula1);
formulas1.Append(formula2);
formulas1.Append(formula3);
formulas1.Append(formula4);
formulas1.Append(formula5);
formulas1.Append(formula6);
formulas1.Append(formula7);
formulas1.Append(formula8);
formulas1.Append(formula9);
formulas1.Append(formula10);
formulas1.Append(formula11);
formulas1.Append(formula12);
formulas1.Append(formula13);
formulas1.Append(formula14);
var path1 = new Path()
{
AllowTextPath = DocumentFormat.OpenXml.Vml.BooleanValues.True,
ConnectionPointType = ConnectValues.Custom,
ConnectionPoints = "@9,0;@10,10800;@11,21600;@12,10800",
ConnectAngles = "270,180,90,0"
};
var textPath1 = new TextPath()
{
On = DocumentFormat.OpenXml.Vml.BooleanValues.True,
FitShape = DocumentFormat.OpenXml.Vml.BooleanValues.True
};
var shapeHandles1 = new Handles();
var shapeHandle1 = new Handle()
{
Position = "#0,bottomRight",
XRange = "6629,14971"
};
shapeHandles1.Append(shapeHandle1);
var lock1 = new Lock
{
Extension = ExtensionHandlingBehaviorValues.Edit,
TextLock = DocumentFormat.OpenXml.Vml.Office.BooleanValues.True,
ShapeType = DocumentFormat.OpenXml.Vml.Office.BooleanValues.True
};
shapetype1.Append(formulas1);
shapetype1.Append(path1);
shapetype1.Append(textPath1);
shapetype1.Append(shapeHandles1);
shapetype1.Append(lock1);
var shape1 = new Shape()
{
Id = "PowerPlusWaterMarkObject357476642",
Style = "position:absolute;left:0;text-align:left;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",
OptionalString = "_x0000_s2049",
AllowInCell = DocumentFormat.OpenXml.Vml.BooleanValues.False,
FillColor = "silver",
Stroked = DocumentFormat.OpenXml.Vml.BooleanValues.False,
Type = "#_x0000_t136"
};
var fill1 = new Fill() { Opacity = ".5" };
TextPath textPath2 = new TextPath()
{
Style = "font-family:\"Calibri\";font-size:1pt",
String = "DRAFT"
};
var textWrap1 = new TextWrap()
{
AnchorX = HorizontalAnchorValues.Margin,
AnchorY = VerticalAnchorValues.Margin
};
shape1.Append(fill1);
shape1.Append(textPath2);
shape1.Append(textWrap1);
picture1.Append(shapetype1);
picture1.Append(shape1);
run1.Append(runProperties1);
run1.Append(picture1);
paragraph2.Append(paragraphProperties2);
paragraph2.Append(run1);
sdtContentBlock1.Append(paragraph2);
sdtBlock1.Append(sdtProperties1);
sdtBlock1.Append(sdtContentBlock1);
headerPart.Header.Append(sdtBlock1);
headerPart.Header.Save();
//break;
}
}
}
}
更新:
现在通过更改打开文件的方式解决了这个问题。当我们将 Main 函数更改为:
static void Main(string[] args)
{
//var doc = WordprocessingDocument.Open(@"C:\Users\loggedinuser\Desktop\TestDoc.docx", true);
//AddWatermark(doc);
//doc.MainDocumentPart.Document.Save();
byte[] sourceBytes = File.ReadAllBytes(@"C:\Users\loggedinuser\Desktop\TestDoc.docx");
MemoryStream inMemoryStream = new MemoryStream();
inMemoryStream.Write(sourceBytes, 0, (int)sourceBytes.Length);
var doc = WordprocessingDocument.Open(inMemoryStream, true);
AddWatermark(doc);
doc.MainDocumentPart.Document.Save();
doc.Close();
doc.Dispose();
doc = null;
using (FileStream fileStream = new FileStream(@"C:\Users\loggedinuser\Desktop\TestDoc.docx", System.IO.FileMode.Create))
{
inMemoryStream.WriteTo(fileStream);
}
inMemoryStream.Close();
inMemoryStream.Dispose();
inMemoryStream = null;
}
文档现在可以在 word 中正确打开。谢谢布拉德!
最佳答案
现在通过更改打开文件的方式解决了这个问题。当我们将 Main 函数更改为:
static void Main(string[] args)
{
//var doc = WordprocessingDocument.Open(@"C:\Users\loggedinuser\Desktop\TestDoc.docx", true);
//AddWatermark(doc);
//doc.MainDocumentPart.Document.Save();
byte[] sourceBytes = File.ReadAllBytes(@"C:\Users\loggedinuser\Desktop\TestDoc.docx");
MemoryStream inMemoryStream = new MemoryStream();
inMemoryStream.Write(sourceBytes, 0, (int)sourceBytes.Length);
var doc = WordprocessingDocument.Open(inMemoryStream, true);
AddWatermark(doc);
doc.MainDocumentPart.Document.Save();
doc.Close();
doc.Dispose();
doc = null;
using (FileStream fileStream = new FileStream(@"C:\Users\loggedinuser\Desktop\TestDoc.docx", System.IO.FileMode.Create))
{
inMemoryStream.WriteTo(fileStream);
}
inMemoryStream.Close();
inMemoryStream.Dispose();
inMemoryStream = null;
}
文档现在可以在 word 中正确打开。感谢 Sonoma Partners 的同事 Brad B. 发现了这个!
关于c# - Open XML - 如何向 docx 文档添加水印,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7002341/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为