我正在使用OpenXML和C#生成Word文档。我想阻止(只读)文本中的一个段落,以便在用户编辑时无法将其删除。
我进行了一些不成功的测试,使整个文档变为只读,但这不是我想要的。
var file = $"{directory}\\{fileName}.docx";
using (WordprocessingDocument package =
WordprocessingDocument.Create(file, WordprocessingDocumentType.Document))
{
package.AddMainDocumentPart();
var documentProtection = new DocumentProtection();
documentProtection.Edit = DocumentProtectionValues.ReadOnly;
package.MainDocumentPart.AddNewPart<DocumentSettingsPart>();
package.MainDocumentPart.DocumentSettingsPart.Settings = new Settings();
package.MainDocumentPart.DocumentSettingsPart.Settings.AppendChild(documentProtection);
package.MainDocumentPart.DocumentSettingsPart.Settings.Save();
package.MainDocumentPart.Document = new Document(DocBody);
package.MainDocumentPart.Document.Save();
Process.Start(file);
}
下面是我编写的用于生成段落的代码:
var paragraph = new Paragraph();
var run = new Run();
var properties = new RunProperties();
var paragraphProperties = new ParagraphProperties();
properties.FontSize = new FontSize();
properties.FontSize.Val = new StringValue("20");
properties.RunFonts = new RunFonts()
{
Ascii = "Arial"
};
paragraphProperties.Justification = new Justification() { Val = JustificationValues.Center };
paragraph.Append(paragraphProperties);
run.Append(properties);
var text = new Text("Text content...") { Space = SpaceProcessingModeValues.Preserve };
run.Append(text);
paragraph.Append(run);
DocBody.Append(paragraph);
谢谢!
[实用(但不是100%安全)的解决方案是将受保护的一个或多个段落包装在锁定的Rich Text内容控件中,即SdtBlock
的实例被配置为用户无法编辑或删除内容控件及其内容。
这里有一些示例标记,显示了锁定的内容控件,该控件具有以这种方式保护的段落,而该内容控件之外的另一个段落。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:body>
<w:sdt>
<w:sdtPr>
<w:lock w:val="sdtContentLocked"/>
</w:sdtPr>
<w:sdtContent>
<w:p>
<w:r>
<w:t>This is a protected paragraph.</w:t>
</w:r>
</w:p>
</w:sdtContent>
</w:sdt>
<w:p>
<w:r>
<w:t>This is another, unprotected paragraph.</w:t>
</w:r>
</w:p>
</w:body>
</w:document>
注意w:lock
元素,由Open XML SDK中的Lock
类表示。
创建上述w:sdt
元素所需的C#代码如下:
var sdt =
new SdtBlock(
new SdtProperties(
new Lock { Val = LockingValues.SdtContentLocked }),
new SdtContentBlock(
new Paragraph(
new Run(
new Text("This is a protected paragraph.")))));