Führen Sie mehrere Word-Dokumente mit offenem XML zusammenC#

Ein Treffpunkt für C#-Programmierer
Guest
 Führen Sie mehrere Word-Dokumente mit offenem XML zusammen

Post by Guest »

Ich verwende Open XML, um mehrere Dokumente zusammenzuführen. Ich habe mich um Stil, Beziehungen und Bilder gekümmert, aber in der Ausgabe für jede Seite sehe ich Kopf- und Fußzeilen für alle zusammengeführten Dokumente. Was ich brauche, ist, dass die Seiten jedes zusammengeführten Dokuments ihre eigenen Kopf- und Fußzeilen haben. Zum Beispiel sollte ich für Seiten für Datei 1 nur Kopf- und Fußzeilen von Datei 1 sehen und fortfahren ...
In diesem Beispiel erhalte ich Dateien von meinem einen Laufwerk und erhalte deren Stream.< /p>
Irgendeine Idee, wie ich dieses Ziel erreichen kann?

Code: Select all

    public async Task MergeMultipleDocumentsAsync(
string accessToken,
string fileName,
bool isByPath,
IEnumerable files,
int pageBreaks)
{
var tempFilePath = Path.Combine(Path.GetTempPath(), fileName);
var outputStream = new FileStream(tempFilePath, FileMode.Create, FileAccess.ReadWrite);

using (var mergedDoc = WordprocessingDocument.Create(outputStream, WordprocessingDocumentType.Document, true))
{
var mainPart = mergedDoc.AddMainDocumentPart();
mainPart.Document = new Document();
var mainBody = new Body();
mainPart.Document.AppendChild(mainBody);

bool isFirst = true;

foreach (var file in files)
{
var client = _clientFactory.CreateClient();
client.SetBearerToken(accessToken);
string endpoint = !isByPath
? $"{baseUrl}/me/drive/items/{file}/content"
: $"{baseUrl}/me{FixPath(file)}:/content";

HttpResponseMessage response = await client.GetAsync(endpoint);
if (!response.IsSuccessStatusCode)
{
throw new Exception($"Failed to fetch the file: {response.StatusCode}");
}

using var stream = await response.Content.ReadAsStreamAsync();
using (var sourceDoc = WordprocessingDocument.Open(stream, false))
{
var srcMainPart = sourceDoc.MainDocumentPart;

CopyBodyWithHeadersFooters(srcMainPart, mainPart, mainBody, isFirst);

CopyStylesAndNumbering(srcMainPart, mainPart);
CopyImages(srcMainPart, mainPart);
}

isFirst = false;
}

mainPart.Document.Save();
}

var metadata = new FileMetadata
{
ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
Name = $"{fileName}.docx",
Size = outputStream.Length
};

outputStream.Seek(0, SeekOrigin.Begin);
return (outputStream, metadata);
}

private void CopyBodyWithHeadersFooters(MainDocumentPart srcMainPart, MainDocumentPart targetMainPart, Body targetBody, bool isFirst)
{
var srcBody = srcMainPart.Document.Body;

// Create a new SectionProperties for the section
var sectionProps = new SectionProperties();

// Add section type to ensure section break
if (!isFirst)
{
sectionProps.AppendChild(new SectionType() { Val = SectionMarkValues.NextPage });
}

// Process headers for this section
if (srcMainPart.HeaderParts.Any())
{
foreach (var headerPart in srcMainPart.HeaderParts)
{
var newHeaderPart = targetMainPart.AddNewPart();
using (var stream = headerPart.GetStream())
{
newHeaderPart.FeedData(stream);
}

var sourceHeaderReference = srcBody
.Descendants()
.SelectMany(sp => sp.Elements())
.FirstOrDefault(hr =>  srcMainPart.GetIdOfPart(headerPart) == hr.Id);

if (sourceHeaderReference != null)
{
var headerReference = new HeaderReference
{
Id = targetMainPart.GetIdOfPart(newHeaderPart),
Type = sourceHeaderReference.Type
};
sectionProps.AppendChild(headerReference);
}
}
}

// Process footers for this section
if (srcMainPart.FooterParts.Any())
{
foreach (var footerPart in srcMainPart.FooterParts)
{
var newFooterPart = targetMainPart.AddNewPart();
using (var stream = footerPart.GetStream())
{
newFooterPart.FeedData(stream);
}

var sourceFooterReference = srcBody
.Descendants()
.SelectMany(sp => sp.Elements())
.FirstOrDefault(fr => srcMainPart.GetIdOfPart(footerPart) == fr.Id);

if (sourceFooterReference != null)
{
var footerReference = new FooterReference
{
Id = targetMainPart.GetIdOfPart(newFooterPart),
Type = sourceFooterReference.Type
};
sectionProps.AppendChild(footerReference);
}
}
}

// Add a page break for non-first sections
if (!isFirst)
{
targetBody.AppendChild(new Paragraph(new Run(new Break { Type = BreakValues.Page })));
}

// Copy content from source body
foreach (var element in srcBody.Elements())
{
if (element is not SectionProperties)
{
targetBody.AppendChild(element.CloneNode(true));
}
}

// Add section properties at the end of each document's content
targetBody.AppendChild(new Paragraph(sectionProps));
}

private void CopyStylesAndNumbering(MainDocumentPart srcMainPart, MainDocumentPart targetMainPart)
{
if (srcMainPart.StyleDefinitionsPart != null)
{
var targetStylesPart = targetMainPart.StyleDefinitionsPart ?? targetMainPart.AddNewPart();
targetStylesPart.Styles = (Styles)srcMainPart.StyleDefinitionsPart.Styles.Clone();
}

if (srcMainPart.NumberingDefinitionsPart != null)
{
var targetNumberingPart = targetMainPart.NumberingDefinitionsPart ?? targetMainPart.AddNewPart();
targetNumberingPart.Numbering = (Numbering)srcMainPart.NumberingDefinitionsPart.Numbering.Clone();
}
}

private void CopyImages(MainDocumentPart srcMainPart, MainDocumentPart targetMainPart)
{
foreach (var imagePart in srcMainPart.ImageParts)
{
var newImagePart = targetMainPart.AddImagePart(imagePart.ContentType);
using (var stream = imagePart.GetStream())
{
newImagePart.FeedData(stream);
}

var oldRelId = srcMainPart.GetIdOfPart(imagePart);
var newRelId = targetMainPart.GetIdOfPart(newImagePart);

foreach (var blip in targetMainPart.Document.Body.Descendants())
{
if (blip.Embed?.Value == oldRelId)
{
blip.Embed.Value = newRelId;
}
}
}
}

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post