如何用OpenXML(C#)在Word文档中插入自动更新的当日日期
用OpenXML在Word文档页眉中插入自动刷新的当日日期
需要扩展现有的InsertHeader方法,在传入的text内容中间插入自动更新的当日日期,效果和Word内置的自动日期功能一致(打开文档时自动刷新为当前日期)。
修改后的完整代码
public static byte[] InsertHeader(byte[] buffer, string text, string decisionNumber) { using (var stream = new MemoryStream()) { stream.Write(buffer, 0, buffer.Length); using (var wordDocument = WordprocessingDocument.Open(stream, true)) { var mainPart = wordDocument.MainDocumentPart; var relationshipId = GenerateUniqueRelationshipId(mainPart); var headerPart = mainPart.AddNewPart<HeaderPart>(relationshipId); var relationshipId2 = GenerateUniqueRelationshipId(mainPart); var headerPart2 = mainPart.AddNewPart<HeaderPart>(relationshipId2); var runProp = new RunProperties(); var runProp2 = new RunProperties(); var runFont = new RunFonts { Ascii = "Lato" }; var runFont2 = new RunFonts { Ascii = "Lato" }; var size = new FontSize { Val = new StringValue("20") }; var size2 = new FontSize { Val = new StringValue("20") }; ParagraphProperties paragraphProperties1 = new ParagraphProperties(); var justification2 = new Justification() { Val = JustificationValues.Right }; paragraphProperties1.Append(justification2); runProp.Append(runFont); runProp.Append(size); runProp2.Append(runFont2); runProp2.Append(size2); // ---------------------- 新增自动日期部分 ---------------------- // 拆分传入的text,用|作为日期插入标记(例如传入"文档生成于|,请查阅") var textSegments = text.Split('|'); if (textSegments.Length != 2) { // 如果没有标记,默认在末尾添加日期 textSegments = new[] { text, "" }; } // 创建自动更新的DATE域Run var dateRun = new Run(); dateRun.PrependChild(runProp.CloneNode(true)); // 复用原有字体样式 // 构造DATE域的结构:Begin -> FieldCode -> Separate -> 初始值 -> End var fieldBegin = new FieldChar { FieldCharType = FieldCharValues.Begin }; var fieldCode = new FieldCode { Text = "DATE \\@ \"yyyy-MM-dd\" \\* MERGEFORMAT" }; var fieldSeparate = new FieldChar { FieldCharType = FieldCharValues.Separate }; var fieldEnd = new FieldChar { FieldCharType = FieldCharValues.End }; // 初始显示的日期(打开Word时会自动刷新) var dateText = new Text { Text = DateTime.Now.ToString("yyyy-MM-dd") }; dateRun.Append(fieldBegin); dateRun.Append(new Run(fieldCode)); dateRun.Append(fieldSeparate); dateRun.Append(new Run(dateText)); dateRun.Append(fieldEnd); // ---------------------- 自动日期部分结束 ---------------------- // 构造页眉段落:text前半段 + 日期 + text后半段 var headerParagraph = new Paragraph(); // 添加text前半段 var textBeforeRun = new Run(new Text(textSegments[0])); textBeforeRun.PrependChild(runProp.CloneNode(true)); headerParagraph.Append(textBeforeRun); // 添加日期Run headerParagraph.Append(dateRun); // 添加text后半段 var textAfterRun = new Run(new Text(textSegments[1])); textAfterRun.PrependChild(runProp.CloneNode(true)); headerParagraph.Append(textAfterRun); var header = new Header(headerParagraph); header.Save(headerPart); var paragraph2 = new Paragraph(); paragraph2.Append(paragraphProperties1); var run2 = new Run(new Text(decisionNumber)); run2.PrependChild(runProp2); paragraph2.Append(run2); var header2 = new Header(paragraph2); header2.Save(headerPart2); DocumentFormat.OpenXml.Wordprocessing.SectionProperties sectionProps = mainPart.Document.Body.Elements<DocumentFormat.OpenXml.Wordprocessing.SectionProperties>().FirstOrDefault(); if (sectionProps == null) { sectionProps = new DocumentFormat.OpenXml.Wordprocessing.SectionProperties(); mainPart.Document.Body.Append(sectionProps); } var headerReference = new HeaderReference() { Id = relationshipId, Type = HeaderFooterValues.First }; var headerReference2 = new HeaderReference() { Id = relationshipId2 }; sectionProps.RemoveAllChildren<HeaderReference>(); sectionProps.PrependChild(new TitlePage()); sectionProps.Append(headerReference); sectionProps.Append(headerReference2); mainPart.Document.Save(); } buffer = stream.ToArray(); } return buffer; }
关键说明
- 自动日期实现:通过Word的
DATE域实现自动刷新,\\@ \"yyyy-MM-dd\"指定日期格式,\\* MERGEFORMAT确保格式在刷新后保留。打开Word文档时,该日期会自动更新为当前系统日期。 - 插入位置控制:通过传入的
text中的|标记指定插入位置,例如传入"报告生成于|,版本:V1.0",日期会插入到|的位置;如果没有|标记,默认将日期添加到text末尾。 - 格式一致性:日期Run复用了原有text的字体(Lato)和字号(20号),保证页眉样式统一。
内容的提问来源于stack exchange,提问作者Lukasz
相关产品推荐
相关产品推荐

