Zapisz zmodyfikowany WordprocessingDocument do nowego pliku

Próbuję otworzyć dokument programu Word, zmienić tekst, a następnie zapisać zmiany w nowym dokumencie. Mogę zrobić pierwszy bit używając poniższego kodu, ale nie mogę dowiedzieć się, jak zapisać zmiany w nowym dokumencie (podając ścieżkę i nazwę pliku).

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);
            }
        }
      }
    }
}

Jestem w tym całkowicie początkujący, więc wybacz podstawowe pytanie!

Author: Jehof, 2012-01-11

6 answers

Jeśli używasz MemoryStream możesz zapisać zmiany do nowego pliku w następujący sposób:

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()); 
}
 30
Author: amurra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-11 11:55:09

W Open XML SDK 2.5:

    File.Copy(originalFilePath, modifiedFilePath);

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

wordprocessingDocument.AutoSave domyślnie jest prawdziwe, więc zamknij i pozbądź się zapisze zmiany. {[2] } nie jest potrzebna jawnie, ponieważ using block ją wywoła.

Takie podejście nie wymaga załadowania całej zawartości pliku do pamięci, jak w accepted answer. Nie jest to problem dla małych plików, ale w moim przypadku muszę przetwarzać więcej plików docx z osadzoną zawartością XLSX i pdf w tym samym czasie, więc zużycie pamięci byłoby dość wysokie.

 6
Author: user3285954,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-31 13:37:34

Po prostu skopiuj plik źródłowy do miejsca docelowego i wprowadź stamtąd zmiany.

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();
    }
Mam nadzieję, że to zadziała.
 3
Author: Mohamed Alikhan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-27 07:08:08

To podejście pozwala na buforowanie pliku "template" bez grupowania całości do byte[], co może być mniej zasobochłonne.

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
Author: pimbrouwers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-17 12:20:10

Podstawowym zasobem Open XML jest openxmldeveloper.org. ma kilka prezentacji i przykładowych projektów do manipulowania dokumentami:

Http://openxmldeveloper.org/resources/workshop/m/presentations/default.aspx

Zobacz także następujące pytanie:

Czytanie tabeli Word 2007 przy użyciu C #

 0
Author: Sabuncu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:19

Dla mnie to działało dobrze:

// To search and replace content in a document part.
public static void SearchAndReplace(string document)
{
    using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(document, true))
    {
        string docText = null;
        using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
        {
            docText = sr.ReadToEnd();
        }

        Regex regexText = new Regex("Hello world!");
        docText = regexText.Replace(docText, "Hi Everyone!");

        using (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
        {
            sw.Write(docText);
        }
    }
}
 -2
Author: ren,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-03 14:21:05