Как скопировать содержимое в новый документ Word и заменить текст в новом документе

Я пытаюсь прочитать весь текст в текстовом документе, перевести его и открыть в новом документе с переведенным текстом. Я уже скопировал содержимое в новый документ. Как мне перевести текущий текст по диапазону и вставить текст перевода в правильный диапазон?

Вот что я пытаюсь реализовать.

    //Create new document
    var wordApp = new Microsoft.Office.Interop.Word.Application();
    try
    {
       Document translatedDoc = wordApp.Documents.Add();

       //Get content from existing doc
        var doc = Globals.ThisAddIn.Application.ActiveDocument;
        Range oRange = doc.Content;


        //paste to new documnent
        translatedDoc.Content.PasteSpecial(DataType: WdPasteOptions.wdKeepSourceFormatting);

        var paragraphs = doc.Paragraphs;
        foreach (Paragraph paragraph in paragraphs)
        {
            Range rng = paragraph.Range;
            string pText = paragraph.Range.Text;

            var translated = DocSentenseTranslate(pText);

            //How do i replace the translated text ?
                    
            Marshal.ReleaseComObject(rng);
       }

     wordApp.Visible = true;
  }
  catch (Exception)
  {
     throw;
  }

person Sandun Tharaka    schedule 23.11.2020    source источник
comment
Пожалуйста, простите меня, если я что-то упустил. Кажется ненужным копировать и вставлять исходный текст в новый документ, если вам все равно приходится «переводить» каждый абзац. Я думаю, что лучшим подходом было бы открыть исходный документ для чтения и создать новый документ для записи. Затем прокрутите каждый абзац в исходном документе... получите строку из абзаца, затем вызовите DocSentenseTranslate(pText); и добавьте возвращенную строку в качестве нового абзаца в новый документ. Может потребоваться дополнительный шаг, так как неясно, что возвращается из DocSentenseTranslate(pText);   -  person JohnG    schedule 23.11.2020
comment
Привет @JohnG Спасибо. Метод возвращает переведенный текст абзаца. Можете ли вы привести пример, как открыть исходный документ для чтения, создать новый документ для записи. и можем ли мы сохранить формат (существующие изображения..)?   -  person Sandun Tharaka    schedule 23.11.2020
comment
Если вы хотите захватить все, включая изображения и т. д. Тогда я бы посоветовал вам сначала «скопировать» весь файл, затем просмотреть абзацы, получить текст абзаца, перевести текст, затем удалить старый текст и добавить переведенный текст. Неизвестно, как документ отформатирован и т. д., однако, учитывая, что текст переводится, нет ли возможности, что новый «переведенный» текст может занять больше (или меньше) места и, возможно, «изменить» текущий текст поток? Я просто говорю, что, переводя текст, я уверен, что может потребоваться дополнительная работа, поскольку поток текста «может» измениться.   -  person JohnG    schedule 23.11.2020
comment
Кроме того, мне несколько любопытно, «почему» вы хотите использовать взаимодействие для этого. Вы знаете, что можете изменить весь язык в существующем текстовом документе из самого Word. Откройте документ, щелкните правой кнопкой мыши пустое место и выберите «Перевести». Вы можете выбрать между «выделенным» текстом или всем документом. Есть ли какой-то специальный переводчик, который вам нужно использовать?   -  person JohnG    schedule 23.11.2020
comment
@JohnG, да, именно мне нужно интегрировать сторонний API, мне нужно выполнять те же функции, что и переводчик MS. Спасибо за ваш отзыв. Я новичок в VSTO, поэтому можем ли мы создать точную копию слова doc? без копипаст   -  person Sandun Tharaka    schedule 23.11.2020
comment
»Можем ли мы создать точную копию слова doc ? без копирования и вставки” … конечно… откройте документ, затем SaveAs новый документ.   -  person JohnG    schedule 23.11.2020
comment
Спасибо @JohnG, буду следовать тому, что вы здесь упомянули.   -  person Sandun Tharaka    schedule 23.11.2020
comment
Давайте продолжим обсуждение в чате.   -  person Sandun Tharaka    schedule 23.11.2020


Ответы (1)


У вас почти есть это в вашем текущем примере. Я почти уверен, что вы можете просто «заменить» «текст абзаца» на «переведенный текст»… например…

paragraph.Range.Text = translated;

Ниже приведен мой тест, в котором код открывает данный файл (source), сохраняет файл с заданным именем файла пути (dest), затем перебирает каждый абзац в документе и заменяет текст в абзаце переведенным текстом, затем наконец повторно сохраняет новый документ. Я не публиковал метод «перевода», поскольку вы сказали, что у вас есть специальный переводчик для использования. Очевидно, вы бы изменили этот метод на свой метод.

Кроме того, пара замечаний, как видно из моего кода, я настоятельно рекомендую вам структурировать большинство interop методов таким образом… используя try/catch/finally. Это поможет избежать «утечек» ресурсов. Весь код находится в части «попробовать». Часть «поймать» для отображения любых ошибок и важная часть «наконец» для закрытия файла и освобождения ресурсов. Часть «наконец» будет выполняться ВСЕГДА, даже если код выдает исключение.

Кроме того, похоже, что вы можете запускать этот код в BackgroundWorker, это нормально, однако вам нужно быть осторожным и НЕ использовать пользовательский интерфейс, который находится в другом потоке. Я не пробовал это; однако я предполагаю, что у вас могут возникнуть проблемы, если вы попытаетесь выполнить…

wordApp.Visible = true;

на заднем плане рабочий. Это может сработать, и если сработает, то дерзайте… это просто предупреждение… ваш фоновый рабочий процесс НЕ должен пытаться получить доступ к каким-либо элементам пользовательского интерфейса из вызывающего потока. Я предполагаю, что вы, возможно, уже знаете это.

В любом случае, попробуйте приведенный ниже код, так как он работал в моих тестах.

private void TranslateDoc(string source, string dest) {
  Word.Application wordApp = null;
  Word.Document myWordDoc = null;
  try {
    wordApp = new Word.Application();
    if (File.Exists(source)) {
      //wordApp.Visible = true;
      myWordDoc = wordApp.Documents.Open(source);
      myWordDoc.SaveAs2(dest);
      myWordDoc.Close();
      myWordDoc = wordApp.Documents.Open(dest);
      Word.Paragraphs paragraphs = myWordDoc.Paragraphs;
      string originalText;
      string replacementText;
      for (int i = 1; i <= paragraphs.Count; i++) {
        originalText = paragraphs[i].Range.Text;
        if (originalText != "\r") {
          replacementText = TranslateText(originalText);
          paragraphs[i].Range.Text = replacementText;
        }
      }
      myWordDoc.SaveAs2(dest);
      MessageBox.Show("File Created!");
    }
    else {
      MessageBox.Show("Original File not Found!");
    }
  }
  catch (Exception ex) {
    MessageBox.Show("Error: " + ex.Message);
  }
  finally {
    if (myWordDoc != null) {
      myWordDoc.Close();
      Marshal.ReleaseComObject(myWordDoc);
    }
    if (wordApp != null) {
      wordApp.Quit();
      Marshal.ReleaseComObject(wordApp);
    }
  }
}

Использование…

string sourceFileName = @"D:\Test\WordFiles\Translate1.docx";
string destFileName = @"D:\Test\WordFiles\Translate2.docx";

private void button1_Click(object sender, EventArgs e) {
  TranslateDoc(sourceFileName, destFileName);
}
person JohnG    schedule 24.11.2020