web-dev-qa-db-fra.com

Enregistrer WordprocessingDocument modifié dans un nouveau fichier

J'essaie d'ouvrir un document Word, de modifier du texte, puis d'enregistrer les modifications dans un nouveau document. Je peux faire le premier bit en utilisant le code ci-dessous mais je ne peux pas comprendre comment enregistrer les modifications dans un nouveau document (en spécifiant le chemin et le nom du fichier).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using DocumentFormat.OpenXml.Packaging;
using System.IO;

namespace WordTest
{
class Program
{
    static void Main(string[] args)
    {
        string template = @"c:\data\hello.docx";
        string documentText;

        using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(template, true))
        {
            using (StreamReader reader = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
            {
                documentText = reader.ReadToEnd();
            }


            documentText = documentText.Replace("##Name##", "Paul");
            documentText = documentText.Replace("##Make##", "Samsung");

            using (StreamWriter writer = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
            {
                writer.Write(documentText);
            }
        }
      }
    }
}

Je suis un débutant complet dans ce domaine, alors pardonnez la question de base!

36
Paul

Si vous utilisez un MemoryStream, vous pouvez enregistrer les modifications dans un nouveau fichier comme celui-ci:

byte[] byteArray = File.ReadAllBytes("c:\\data\\hello.docx");
using (MemoryStream stream = new MemoryStream())
{
    stream.Write(byteArray, 0, (int)byteArray.Length);
    using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(stream, true))
    {
       // Do work here
    }
    // Save the file with the new name
    File.WriteAllBytes("C:\\data\\newFileName.docx", stream.ToArray()); 
}
34
amurra

Dans Open XML SDK 2.5:

    File.Copy(originalFilePath, modifiedFilePath);

    using (var wordprocessingDocument = WordprocessingDocument.Open(modifiedFilePath, isEditable: true))
    {
        // Do changes here...
    }

wordprocessingDocument.AutoSave est vrai par défaut, donc Close and Dispose enregistrera les modifications. wordprocessingDocument.Close n'est pas nécessaire explicitement car le bloc using l'appellera.

Cette approche n'exige pas que le contenu du fichier entier soit chargé en mémoire comme dans la réponse acceptée. Ce n'est pas un problème pour les petits fichiers, mais dans mon cas, je dois traiter plus de fichiers docx avec du contenu xlsx et pdf intégré en même temps, donc l'utilisation de la mémoire serait assez élevée.

8
user3285954

Copiez simplement le fichier source vers la destination et apportez des modifications à partir de là.

File.copy(source,destination);
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(destination, true))
    {
       \\Make changes to the document and save it.
       WordDoc.MainDocumentPart.Document.Save();
       WordDoc.Close();
    }

J'espère que cela fonctionne.

4
Mohamed Alikhan

Cette approche vous permet de mettre le fichier "modèle" en mémoire tampon sans regrouper le tout dans un byte[], ce qui lui permet peut-être d'être moins gourmande en ressources.

var templatePath = @"c:\data\hello.docx";
var documentPath = @"c:\data\newFilename.docx";

using (var template = File.OpenRead(templatePath))
using (var documentStream = File.Open(documentPath, FileMode.OpenOrCreate))
{
    template.CopyTo(documentStream);

    using (var document = WordprocessingDocument.Open(documentStream, true))
    {
        //do your work here

        document.MainDocumentPart.Document.Save();
    }
}
1
pim