结合eventHanlder和openXMl 实现上传word文档加页眉,页脚
结合eventHanlder和openXMl 实现上传word文档加页眉,页脚
先要引用windowsbase.dll 还有下载DocumentFormat.OpenXml
其他不多说,直接贴代码


using System;
using System.Security.Permissions;
using System.Runtime.InteropServices;
using Microsoft.SharePoint;
using System.IO;
using System.IO.Packaging;
using DocumentFormat.OpenXml.Packaging;
using System.Xml;
using System.Collections.Generic;
namespace AddHeaderFooterReceiver
{
public class AddHeaderFooterEventReceiver : SPItemEventReceiver
{
public string GetFooter()
{
string footerVal = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><w:ftr xmlns:ve=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" xmlns:w10=\"urn:schemas-microsoft-com:office:word\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\"><w:p w:rsidR=\"00C24C70\" w:rsidRDefault=\"00C24C70\"><w:pPr><w:pStyle w:val=\"Footer\" /></w:pPr><w:r><w:t>Hi</w:t></w:r></w:p><w:p w:rsidR=\"00C24C70\" w:rsidRDefault=\"00C24C70\"><w:pPr><w:pStyle w:val=\"Footer\" /></w:pPr></w:p></w:ftr>";
return footerVal;
}
public string GetHeader()
{
string headerVal = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><w:hdr xmlns:ve=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" xmlns:w10=\"urn:schemas-microsoft-com:office:word\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\"><w:p w:rsidR=\"00C8737A\" w:rsidRDefault=\"00C8737A\"><w:pPr><w:pStyle w:val=\"Header\" /></w:pPr><w:r><w:t>hello</w:t></w:r></w:p><w:p w:rsidR=\"00C8737A\" w:rsidRDefault=\"00C8737A\"><w:pPr><w:pStyle w:val=\"Header\" /> </w:pPr></w:p></w:hdr>";
return headerVal;
}
public void WDAddHeader(Stream headerContent, Stream fileContent)
{
const string documentRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
const string wordmlNamespace = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const string headerContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml";
const string headerRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header";
const string relationshipNamespace = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
PackagePart documentPart = null;
using (Package wdPackage = Package.Open(fileContent, FileMode.Open, FileAccess.ReadWrite))
{
foreach (System.IO.Packaging.PackageRelationship relationship in wdPackage.GetRelationshipsByType(documentRelationshipType))
{
Uri documentUri = PackUriHelper.ResolvePartUri(new Uri("/", UriKind.Relative), relationship.TargetUri);
documentPart = wdPackage.GetPart(documentUri);
break;
}
Uri uriHeader = new Uri("/word/header1.xml", UriKind.Relative);
if (wdPackage.PartExists(uriHeader))
{
wdPackage.DeletePart(uriHeader);
}
PackagePart headerPart = wdPackage.CreatePart(uriHeader, headerContentType);
XmlDocument headerDoc = new XmlDocument();
headerContent.Position = 0;
headerDoc.Load(headerContent);
headerDoc.Save(headerPart.GetStream());
PackageRelationship rel = documentPart.CreateRelationship(uriHeader, TargetMode.Internal, headerRelationshipType);
string relID = rel.Id;
NameTable nt = new NameTable();
XmlNamespaceManager nsManager = new XmlNamespaceManager(nt);
nsManager.AddNamespace("w", wordmlNamespace);
XmlDocument xdoc = new XmlDocument(nt);
xdoc.Load(documentPart.GetStream());
XmlNode targetNode = xdoc.SelectSingleNode("//w:sectPr", nsManager);
if (targetNode != null)
{
// Delete any existing references to headers.
XmlNodeList headerNodes = targetNode.SelectNodes("./w:headerReference", nsManager);
foreach (System.Xml.XmlNode headerNode in headerNodes)
{
targetNode.RemoveChild(headerNode);
}
XmlElement node = xdoc.CreateElement("w:headerReference", wordmlNamespace);
XmlAttribute attr = node.Attributes.Append(xdoc.CreateAttribute("r:id", relationshipNamespace));
attr.Value = relID;
node.Attributes.Append(attr);
targetNode.InsertBefore(node, targetNode.FirstChild);
}
xdoc.Save(documentPart.GetStream(FileMode.Create, FileAccess.Write));
}
}
public void WDAddFooter(Stream footerContent, Stream fileContent)
{
const string documentRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
const string wordmlNamespace = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
const string footerContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml";
const string footerRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer";
const string relationshipNamespace = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
PackagePart documentPart = null;
using (Package wdPackage = Package.Open(fileContent, FileMode.Open, FileAccess.ReadWrite))
{
// 获取文件主要部分 (document.xml).
foreach (System.IO.Packaging.PackageRelationship relationship in wdPackage.GetRelationshipsByType(documentRelationshipType))
{
Uri documentUri = PackUriHelper.ResolvePartUri(new Uri("/", UriKind.Relative), relationship.TargetUri);
documentPart = wdPackage.GetPart(documentUri);
break;
}
Uri uriFooter = new Uri("/word/footer1.xml", UriKind.Relative);
if (wdPackage.PartExists(uriFooter))
{
wdPackage.DeletePart(uriFooter);
}
PackagePart footerPart = wdPackage.CreatePart(uriFooter, footerContentType);
XmlDocument footerDoc = new XmlDocument();
footerContent.Position = 0;
footerDoc.Load(footerContent);
footerDoc.Save(footerPart.GetStream());
PackageRelationship rel = documentPart.CreateRelationship(uriFooter, TargetMode.Internal, footerRelationshipType);
string relID = rel.Id;
NameTable nt = new NameTable();
XmlNamespaceManager nsManager = new XmlNamespaceManager(nt);
nsManager.AddNamespace("w", wordmlNamespace);
XmlDocument xdoc = new XmlDocument(nt);
xdoc.Load(documentPart.GetStream());
XmlNode targetNode = xdoc.SelectSingleNode("//w:sectPr", nsManager);
if (targetNode != null)
{
// 删除存在的页脚
XmlNodeList footerNodes = targetNode.SelectNodes("./w:footerReference", nsManager);
foreach (System.Xml.XmlNode footerNode in footerNodes)
{
targetNode.RemoveChild(footerNode);
}
// 创建新的页脚节点
XmlElement node = xdoc.CreateElement("w:footerReference", wordmlNamespace);
XmlAttribute attr = node.Attributes.Append(xdoc.CreateAttribute("r:id", relationshipNamespace));
attr.Value = relID;
node.Attributes.Append(attr);
targetNode.InsertBefore(node, targetNode.FirstChild);
}
// 保存xml
xdoc.Save(documentPart.GetStream(FileMode.Create, FileAccess.Write));
}
}
public override void ItemAdded(SPItemEventProperties properties)
{
string extension = properties.ListItem.Url.Substring(properties.ListItem.Url.LastIndexOf(".") + 1);
if (extension == "docx")
{
string headerContent = GetHeader().Replace("hello", properties.ListItem["Name"].ToString());
string footerContent = GetFooter().Replace("Hi", properties.ListItem["Modified"].ToString());
Stream headerStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(headerContent));
Stream footerStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(footerContent));
MemoryStream fileStream = new MemoryStream();
fileStream.Write(properties.ListItem.File.OpenBinary(), 0, (int)properties.ListItem.File.TotalLength);
WDAddHeader(headerStream, fileStream);
WDAddFooter(footerStream, fileStream);
properties.ListItem.File.SaveBinary(fileStream);
}
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述