使用OpenXML SDK 2.0 CTP,我尝试以编程方式创建Word文档。在我的文档中,我必须插入一个项目符号列表,列表中的一些元素必须加下划线。我怎样才能做到这一点?OpenXML 2 SDK - Word文档 - 以编程方式创建项目符号列表
回答
OpenXML中的列表有点混淆。
有一个NumberingDefinitions部分描述文档中的所有列表。它包含有关列表应该如何显示(项目符号,编号等)以及每个项目分配和ID的信息。
然后在MainDocumentPart中,对于要创建的列表中的每个项目,都需要添加一个新段落并将该列表的ID分配给该段落。
所以要建立一个符号列表,例如:
- 你好,
- 世界!
您必须首先创建一个NumberingDefinitionsPart:
NumberingDefinitionsPart numberingPart =
mainDocumentPart.AddNewPart<NumberingDefinitionsPart>("someUniqueIdHere");
Numbering element =
new Numbering(
new AbstractNum(
new Level(
new NumberingFormat() {Val = NumberFormatValues.Bullet},
new LevelText() {Val = "·"}
) {LevelIndex = 0}
){AbstractNumberId = 1},
new NumberingInstance(
new AbstractNumId(){Val = 1}
){NumberID = 1});
element.Save(numberingPart);
然后创建MainDocumentPart像往常一样,除了在段落属性,分配的编号ID:
MainDocumentPart mainDocumentPart =
package.AddMainDocumentPart();
Document element =
new Document(
new Body(
new Paragraph(
new ParagraphProperties(
new NumberingProperties(
new NumberingLevelReference(){ Val = 0 },
new NumberingId(){ Val = 1 })),
new Run(
new RunProperties(),
new Text("Hello, "){ Space = "preserve" })),
new Paragraph(
new ParagraphProperties(
new NumberingProperties(
new NumberingLevelReference(){ Val = 0 },
new NumberingId(){ Val = 1 })),
new Run(
new RunProperties(),
new Text("world!"){ Space = "preserve" }))));
element.Save(mainDocumentPart);
第2.9节中对OpenXML reference guide中提供的选项有更好的解释。
以上亚当的回答是,除了它正确的是新NumberingInstance(而不是新的NUM(如在注释中提到。
此外,如果您有多个列表,你应该有多个编号的元素(每个都有它自己的ID例如1,2,3等 - 对于文档中的每个列表,这似乎没有问题,但编号列表将继续使用相同的编号顺序(而不是从1重新开始)因为它会认为它是相同的列表。NumberingId必须在您的段落中引用,如下所示:
ParagraphProperties paragraphProperties1 = new ParagraphProperties();
ParagraphStyleId paragraphStyleId1 = new ParagraphStyleId() { Val = "ListParagraph" };
NumberingProperties numberingProperties1 = new NumberingProperties();
NumberingLevelReference numberingLevelReference1 = new NumberingLevelReference() { Val = 0 };
NumberingId numberingId1 = new NumberingId(){ Val = 1 }; //Val is 1, 2, 3 etc based on your numberingid in your numbering element
numberingProperties1.Append(numberingLevelReference1);
numberingProperties1.Append(numberingId1);
paragraphProperties1.Append(paragraphStyleId1);
paragraphProperties1.Append(numberingProperties1);
Level元素的子元素将对子弹类型和缩进产生影响。 我的子弹太小了,直到我说这水平元素:
new NumberingSymbolRunProperties(
new RunFonts() { Hint = FontTypeHintValues.Default, Ascii = "Symbol", HighAnsi = "Symbol" })
缩进是一个问题,直到我加入此元素的水平元素,以及:
new PreviousParagraphProperties(
new Indentation() { Left = "864", Hanging = "360" })
如果你是喜欢我 - 从模板创建文档,然后您可能需要使用此代码来处理这两种情况 - 当您的模板包含或不包含任何编号定义时:
// Introduce bulleted numbering in case it will be needed at some point
NumberingDefinitionsPart numberingPart = document.MainDocumentPart.NumberingDefinitionsPart;
if (numberingPart == null)
{
numberingPart = document.MainDocumentPart.AddNewPart<NumberingDefinitionsPart>("NumberingDefinitionsPart001");
}
我希望能让我在文档中添加多个项目符号列表。在将我的头撞向桌面一段时间之后,我设法合并了一堆不同的帖子,并使用Open XML SDK 2检查了我的文档。0产品工具,并找出了一些东西。它生成的文档现在通过SDK生产力工具版本2.0和2.5的验证。
这是代码;希望它可以节省一些时间和加重。
用法:
const string fileToCreate = "C:\\temp\\bulletTest.docx";
if (File.Exists(fileToCreate))
File.Delete(fileToCreate);
var writer = new SimpleDocumentWriter();
List<string> fruitList = new List<string>() { "Apple", "Banana", "Carrot"};
writer.AddBulletList(fruitList);
writer.AddParagraph("This is a spacing paragraph 1.");
List<string> animalList = new List<string>() { "Dog", "Cat", "Bear" };
writer.AddBulletList(animalList);
writer.AddParagraph("This is a spacing paragraph 2.");
List<string> stuffList = new List<string>() { "Ball", "Wallet", "Phone" };
writer.AddBulletList(stuffList);
writer.AddParagraph("Done.");
writer.SaveToFile(fileToCreate);
using语句:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
代码
public class SimpleDocumentWriter : IDisposable
{
private MemoryStream _ms;
private WordprocessingDocument _wordprocessingDocument;
public SimpleDocumentWriter()
{
_ms = new MemoryStream();
_wordprocessingDocument = WordprocessingDocument.Create(_ms, WordprocessingDocumentType.Document);
var mainDocumentPart = _wordprocessingDocument.AddMainDocumentPart();
Body body = new Body();
mainDocumentPart.Document = new Document(body);
}
public void AddParagraph(string sentence)
{
List<Run> runList = ListOfStringToRunList(new List<string> { sentence});
AddParagraph(runList);
}
public void AddParagraph(List<string> sentences)
{
List<Run> runList = ListOfStringToRunList(sentences);
AddParagraph(runList);
}
public void AddParagraph(List<Run> runList)
{
var para = new Paragraph();
foreach (Run runItem in runList)
{
para.AppendChild(runItem);
}
Body body = _wordprocessingDocument.MainDocumentPart.Document.Body;
body.AppendChild(para);
}
public void AddBulletList(List<string> sentences)
{
var runList = ListOfStringToRunList(sentences);
AddBulletList(runList);
}
public void AddBulletList(List<Run> runList)
{
// Introduce bulleted numbering in case it will be needed at some point
NumberingDefinitionsPart numberingPart = _wordprocessingDocument.MainDocumentPart.NumberingDefinitionsPart;
if (numberingPart == null)
{
numberingPart = _wordprocessingDocument.MainDocumentPart.AddNewPart<NumberingDefinitionsPart>("NumberingDefinitionsPart001");
Numbering element = new Numbering();
element.Save(numberingPart);
}
// Insert an AbstractNum into the numbering part numbering list. The order seems to matter or it will not pass the
// Open XML SDK Productity Tools validation test. AbstractNum comes first and then NumberingInstance and we want to
// insert this AFTER the last AbstractNum and BEFORE the first NumberingInstance or we will get a validation error.
var abstractNumberId = numberingPart.Numbering.Elements<AbstractNum>().Count() + 1;
var abstractLevel = new Level(new NumberingFormat() {Val = NumberFormatValues.Bullet}, new LevelText() {Val = "·"}) {LevelIndex = 0};
var abstractNum1 = new AbstractNum(abstractLevel) {AbstractNumberId = abstractNumberId};
if (abstractNumberId == 1)
{
numberingPart.Numbering.Append(abstractNum1);
}
else
{
AbstractNum lastAbstractNum = numberingPart.Numbering.Elements<AbstractNum>().Last();
numberingPart.Numbering.InsertAfter(abstractNum1, lastAbstractNum);
}
// Insert an NumberingInstance into the numbering part numbering list. The order seems to matter or it will not pass the
// Open XML SDK Productity Tools validation test. AbstractNum comes first and then NumberingInstance and we want to
// insert this AFTER the last NumberingInstance and AFTER all the AbstractNum entries or we will get a validation error.
var numberId = numberingPart.Numbering.Elements<NumberingInstance>().Count() + 1;
NumberingInstance numberingInstance1 = new NumberingInstance() {NumberID = numberId};
AbstractNumId abstractNumId1 = new AbstractNumId() {Val = abstractNumberId};
numberingInstance1.Append(abstractNumId1);
if (numberId == 1)
{
numberingPart.Numbering.Append(numberingInstance1);
}
else
{
var lastNumberingInstance = numberingPart.Numbering.Elements<NumberingInstance>().Last();
numberingPart.Numbering.InsertAfter(numberingInstance1, lastNumberingInstance);
}
Body body = _wordprocessingDocument.MainDocumentPart.Document.Body;
foreach (Run runItem in runList)
{
// Create items for paragraph properties
var numberingProperties = new NumberingProperties(new NumberingLevelReference() {Val = 0}, new NumberingId() {Val = numberId});
var spacingBetweenLines1 = new SpacingBetweenLines() { After = "0" }; // Get rid of space between bullets
var indentation = new Indentation() { Left = "720", Hanging = "360" }; // correct indentation
ParagraphMarkRunProperties paragraphMarkRunProperties1 = new ParagraphMarkRunProperties();
RunFonts runFonts1 = new RunFonts() { Ascii = "Symbol", HighAnsi = "Symbol" };
paragraphMarkRunProperties1.Append(runFonts1);
// create paragraph properties
var paragraphProperties = new ParagraphProperties(numberingProperties, spacingBetweenLines1, indentation, paragraphMarkRunProperties1);
// Create paragraph
var newPara = new Paragraph(paragraphProperties);
// Add run to the paragraph
newPara.AppendChild(runItem);
// Add one bullet item to the body
body.AppendChild(newPara);
}
}
public void Dispose()
{
CloseAndDisposeOfDocument();
if (_ms != null)
{
_ms.Dispose();
_ms = null;
}
}
public MemoryStream SaveToStream()
{
_ms.Position = 0;
return _ms;
}
public void SaveToFile(string fileName)
{
if (_wordprocessingDocument != null)
{
CloseAndDisposeOfDocument();
}
if (_ms == null)
throw new ArgumentException("This object has already been disposed of so you cannot save it!");
using (var fs = File.Create(fileName))
{
_ms.WriteTo(fs);
}
}
private void CloseAndDisposeOfDocument()
{
if (_wordprocessingDocument != null)
{
_wordprocessingDocument.Close();
_wordprocessingDocument.Dispose();
_wordprocessingDocument = null;
}
}
private static List<Run> ListOfStringToRunList(List<string> sentences)
{
var runList = new List<Run>();
foreach (string item in sentences)
{
var newRun = new Run();
newRun.AppendChild(new Text(item));
runList.Add(newRun);
}
return runList;
}
}
- 1. 使用OpenXML SDK创建Word文档 - 使用OpenXML SDK创建CLI
- 2. 如何通过模板以编程方式创建Word文档
- 3. 以编程方式创建Word 2010文档
- 4. 在Apache POI API上使用Java创建Word文档的项目符号列表
- 5. 使用OpenXML创建Word文档
- 6. 使用OpenXml创建Word文档(docx)
- 7. 以编程方式比较word文档
- 8. 如何用Qt创建项目符号或编号列表?
- 9. 如何以编程方式将注释插入Microsoft Word文档?
- 10. 以编程方式在Android中创建列表视图项目
- 11. 使用OpenXml创建Excel文档sdk 2.0
- 12. 创建两列项目符号列表
- 13. 以编程方式访问Word 2007文档的文档属性
- 14. 以编程方式创建VS解决方案/项目文件
- 15. 如何以编程方式在Google文档中创建文档?
- 16. 通过OpenXML生成word文档
- 17. 如何以编程方式将项目符号列表添加到NSTextView
- 18. 如何以编程方式创建NDepend项目文件?
- 19. 以编程方式在Word中创建表格
- 20. 使用OpenXML SDK简单替换Word文档中的标记
- 21. 以编程方式从ASP.NET生成可编辑的Word文档?
- 22. 以编程方式对Word文档进行简单的编辑
- 23. 以编程方式创建选项卡
- 24. OpenXML SDK 2.0 vs Aspose在.NET中用于服务器端word 2007文档生成
- 25. 动态创建openxml文档
- 26. open office java uno API如何创建项目符号列表
- 27. 如何以编程方式创建Firebase项目?
- 28. 以最快的方式以编程方式替换Word文档中的文本
- 29. 以编程方式创建目录
- 30. 以声明方式或编程方式创建Sharepoint列表?
非常感谢你为我展示如何将列表添加到文档中。我使用Numbering.Append(abstactNum,numberingInstance),并不明白为什么它不起作用 – Dan 2017-11-17 08:51:31
从未来:谢谢你的队友!真的! :) – 2018-03-08 15:08:33
@MariusConjeaud不客气。我创建了一些用于编写简单的文档的文档,欢迎使用(请参阅https://github.com/madcodemonkey/SimpleDocument.OpenXML) – 2018-03-10 00:12:13