none
Abrir docx ou doc pelo Windows Application RRS feed

  • Pergunta

  • Preciso fazer o seguinte. Abrir um documento modelo em DOC ou DOCX. Ao abrir, eu preciso substituir umas strings que começam assim: @NOME e colocar o nome que vem de uma base de dados. É necessário algum WordApplication para abrir documentos DOCX ou DOC? Alguém tem alguma sugestão para mim?
    sexta-feira, 6 de julho de 2012 17:50

Respostas

  • Olá Pnet,
    Tudo bem?

    Meu algoritmo ficou assim:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Word = Microsoft.Office.Interop.Word;
    namespace ConsoleApplicationWord
    {
        class Program
        {
            static void Main(string[] args)
            {
                WordReplace x = new WordReplace(@"C:\Users\Fernando\Desktop\replace - Copy.docx");
                x.Replace();
            }
        }
        public class WordReplace
        {
            private string _documentPath;
            public WordReplace(string documentPath)
            {
                this._documentPath = documentPath;
            }
            public void Replace()
            {
                
                Word.Application oApp = new Word.Application();
                Word.Document oDoc = oApp.Documents.Open(this._documentPath);
                ReplateString(oDoc, "[@NOME]", "Olá, enfermeira!");
                // Para não mostrar mensagens quando salvar ou qualquer outra mensagem
                oApp.ShowStartupDialog = false;
                // Salvando de verdade
                oDoc.Save();
                // Removendo o word da lista de processos em execução
                oDoc.Close();
                oApp = null;
            }
            private void ReplateString(Word.Document oDoc, string findText, string replaceText)
            {
                object missing = System.Reflection.Missing.Value;
                object FindText = findText;
                object ReplaceWith = replaceText;
                object MatchWholeWord = true;
                object Forward = false;
                
                Word.Range oRng = oDoc.Range(ref missing, ref missing);
                oRng.Find.Execute(ref FindText, ref missing, ref MatchWholeWord, ref missing, ref missing, ref missing, ref Forward,
                ref missing, ref missing, ref ReplaceWith, ref missing, ref missing, ref missing, ref missing, ref missing);
            }
        }
    }

    Pontos relevantes:
    - Encapsulei seu código de replace em um método, assim fica mais fácil dar manutenção
    - Ao invés de abrir o documento com um "Documents.Add" estou utilizando o "Documents.Open", é um processo mais "natural"
    - A propriedade ShowStartupDialog controla a exibição de mensagems de "Salvar", "Salvar Como", e outros.
    - O problema de abrir o documento e estar como somente leitura é pq estava falando fechar o documento e remover o processo da memória, o que foi resolvido com as linhas
    "oDoc.Close();" e "oApp = null;".

    Qualquer dúvida é só falar.

    []s!


    Fernando Henrique Inocêncio Borba Ferreira
    while(alive){ this.WriteCode(); }
    Blog: http://ferhenriquef.com/
    Twitter: @ferhenrique
    Entity Framework - Brasil: https://www.facebook.com/EntityFrameworkBrasil

    domingo, 8 de julho de 2012 14:49
    Moderador

Todas as Respostas

  • Olá Pnet,
    Tudo beleza?

    Existem dois modos de fazer isso, sendo:

    - Com o Word instalado na máquina cliente vc pode utilizar o Word Interop, como neste link: http://www.dotnetperls.com/word

    - Se o client não tiver o Word instalado vc pode fazer uso de OpenXml ou WordML.

    A solução utilizando Interop é mais fácil.

    []s!


    Fernando Henrique Inocêncio Borba Ferreira
    while(alive){ this.WriteCode(); }
    Blog: http://ferhenriquef.com/
    Twitter: @ferhenrique
    Entity Framework - Brasil: https://www.facebook.com/EntityFrameworkBrasil

    • Sugerido como Resposta rs.developer sábado, 7 de julho de 2012 21:04
    sábado, 7 de julho de 2012 13:11
    Moderador
  • Fiz essa rotina. Coloquei alguns valores fixos apenas para testar e dá erro. Baixei esse código da net:

     class WordFill {
                public void PreencherPorReplace(string CaminhoDocMatriz)
                {
                    object missing = System.Reflection.Missing.Value;
                    Word.Application oApp = new Word.Application();
                    object template = CaminhoDocMatriz;
                    Word.Document oDoc = oApp.Documents.Add(ref template, ref missing, ref missing, ref missing);

                    Word.Range oRng = oDoc.Range(ref missing, ref missing);
                    object FindText = "[@NOME]";
                    object ReplaceWith = "PAULO";
                    object MatchWholeWord = true;
                    object Forward = false;
                    oRng.Find.Execute(ref FindText, ref missing, ref MatchWholeWord, ref missing, ref missing, ref missing, ref Forward,
                    ref missing, ref missing, ref ReplaceWith, ref missing, ref missing, ref missing, ref missing, ref missing);

                    oRng = oDoc.Range(ref missing, ref missing);
                    FindText = "[@CPF]";
                    ReplaceWith = "000.000.000-00";
                    oRng.Find.Execute(ref FindText, ref missing, ref MatchWholeWord, ref missing, ref missing, ref missing, ref Forward,
                    ref missing, ref missing, ref ReplaceWith, ref missing, ref missing, ref missing, ref missing, ref missing);
                    oApp.Visible = true;

                    oRng = oDoc.Range(ref missing, ref missing);
                    FindText = "[@ENDERECO]";
                    ReplaceWith = "azul";
                    MatchWholeWord = true;
                    Forward = false;
                    oRng.Find.Execute(ref FindText, ref missing, ref MatchWholeWord, ref missing, ref missing, ref missing, ref Forward,
                    ref missing, ref missing, ref ReplaceWith, ref missing, ref missing, ref missing, ref missing, ref missing);

                    oRng = oDoc.Range(ref missing, ref missing);
                    FindText = "[@CEP]";
                    ReplaceWith = "Pajero";
                    oRng.Find.Execute(ref FindText, ref missing, ref MatchWholeWord, ref missing, ref missing, ref missing, ref Forward,
                    ref missing, ref missing, ref ReplaceWith, ref missing, ref missing, ref missing, ref missing, ref missing);
                    oApp.Visible = true;

                    FindText = "[@CIDADE]";
                    ReplaceWith = "azul";
                    MatchWholeWord = true;
                    Forward = false;
                    oRng.Find.Execute(ref FindText, ref missing, ref MatchWholeWord, ref missing, ref missing, ref missing, ref Forward,
                    ref missing, ref missing, ref ReplaceWith, ref missing, ref missing, ref missing, ref missing, ref missing);

                    oRng = oDoc.Range(ref missing, ref missing);
                    FindText = "[@UF]";
                    ReplaceWith = "Pajero";
                    oRng.Find.Execute(ref FindText, ref missing, ref MatchWholeWord, ref missing, ref missing, ref missing, ref Forward,
                    ref missing, ref missing, ref ReplaceWith, ref missing, ref missing, ref missing, ref missing, ref missing);
                    oApp.Visible = true;

                    FindText = "[@CONTRATO]";
                    ReplaceWith = "azul";
                    MatchWholeWord = true;
                    Forward = false;
                    oRng.Find.Execute(ref FindText, ref missing, ref MatchWholeWord, ref missing, ref missing, ref missing, ref Forward,
                    ref missing, ref missing, ref ReplaceWith, ref missing, ref missing, ref missing, ref missing, ref missing);

                    oRng = oDoc.Range(ref missing, ref missing);
                    FindText = "[@NOME_BANCO]";
                    ReplaceWith = "Pajero";
                    oRng.Find.Execute(ref FindText, ref missing, ref MatchWholeWord, ref missing, ref missing, ref missing, ref Forward,
                    ref missing, ref missing, ref ReplaceWith, ref missing, ref missing, ref missing, ref missing, ref missing);
                    oApp.Visible = true;

                    FindText = "[@END_BANCO]";
                    ReplaceWith = "azul";
                    MatchWholeWord = true;
                    Forward = false;
                    oRng.Find.Execute(ref FindText, ref missing, ref MatchWholeWord, ref missing, ref missing, ref missing, ref Forward,
                    ref missing, ref missing, ref ReplaceWith, ref missing, ref missing, ref missing, ref missing, ref missing);

                    oRng = oDoc.Range(ref missing, ref missing);
                    FindText = "[@BAI_BANCO]";
                    ReplaceWith = "Pajero";
                    oRng.Find.Execute(ref FindText, ref missing, ref MatchWholeWord, ref missing, ref missing, ref missing, ref Forward,
                    ref missing, ref missing, ref ReplaceWith, ref missing, ref missing, ref missing, ref missing, ref missing);
                    oApp.Visible = true;

                    FindText = "[@CID_BANCO]";
                    ReplaceWith = "azul";
                    MatchWholeWord = true;
                    Forward = false;
                    oRng.Find.Execute(ref FindText, ref missing, ref MatchWholeWord, ref missing, ref missing, ref missing, ref Forward,
                    ref missing, ref missing, ref ReplaceWith, ref missing, ref missing, ref missing, ref missing, ref missing);

                    oRng = oDoc.Range(ref missing, ref missing);
                    FindText = "[@UF_BANCO]";
                    ReplaceWith = "Pajero";
                    oRng.Find.Execute(ref FindText, ref missing, ref MatchWholeWord, ref missing, ref missing, ref missing, ref Forward,
                    ref missing, ref missing, ref ReplaceWith, ref missing, ref missing, ref missing, ref missing, ref missing);
                    oApp.Visible = true;

                    FindText = "[@CEP_BANCO]";
                    ReplaceWith = "azul";
                    MatchWholeWord = true;
                    Forward = false;
                    oRng.Find.Execute(ref FindText, ref missing, ref MatchWholeWord, ref missing, ref missing, ref missing, ref Forward,
                    ref missing, ref missing, ref ReplaceWith, ref missing, ref missing, ref missing, ref missing, ref missing);

                    FindText = "[@VENCTO]";
                    ReplaceWith = "azul";
                    MatchWholeWord = true;
                    Forward = false;
                    oRng.Find.Execute(ref FindText, ref missing, ref MatchWholeWord, ref missing, ref missing, ref missing, ref Forward,
                    ref missing, ref missing, ref ReplaceWith, ref missing, ref missing, ref missing, ref missing, ref missing);

                    oRng = oDoc.Range(ref missing, ref missing);
                    FindText = "[@ASSESSORIA]";
                    ReplaceWith = "Pajero";
                    oRng.Find.Execute(ref FindText, ref missing, ref MatchWholeWord, ref missing, ref missing, ref missing, ref Forward,
                    ref missing, ref missing, ref ReplaceWith, ref missing, ref missing, ref missing, ref missing, ref missing);
                    oApp.Visible = true;

                    FindText = "[@END_ASSE]";
                    ReplaceWith = "azul";
                    MatchWholeWord = true;
                    Forward = false;
                    oRng.Find.Execute(ref FindText, ref missing, ref MatchWholeWord, ref missing, ref missing, ref missing, ref Forward,
                    ref missing, ref missing, ref ReplaceWith, ref missing, ref missing, ref missing, ref missing, ref missing);

                    oRng = oDoc.Range(ref missing, ref missing);
                    FindText = "[@BAI_ASSE]";
                    ReplaceWith = "Pajero";
                    oRng.Find.Execute(ref FindText, ref missing, ref MatchWholeWord, ref missing, ref missing, ref missing, ref Forward,
                    ref missing, ref missing, ref ReplaceWith, ref missing, ref missing, ref missing, ref missing, ref missing);
                    oApp.Visible = true;

                    FindText = "[@CID_ASSE]";
                    ReplaceWith = "azul";
                    MatchWholeWord = true;
                    Forward = false;
                    oRng.Find.Execute(ref FindText, ref missing, ref MatchWholeWord, ref missing, ref missing, ref missing, ref Forward,
                    ref missing, ref missing, ref ReplaceWith, ref missing, ref missing, ref missing, ref missing, ref missing);

                    oRng = oDoc.Range(ref missing, ref missing);
                    FindText = "[@UF_ASSE]";
                    ReplaceWith = "Pajero";
                    oRng.Find.Execute(ref FindText, ref missing, ref MatchWholeWord, ref missing, ref missing, ref missing, ref Forward,
                    ref missing, ref missing, ref ReplaceWith, ref missing, ref missing, ref missing, ref missing, ref missing);
                    oApp.Visible = true;

                    FindText = "[@CEP_ASSE]";
                    ReplaceWith = "azul";
                    MatchWholeWord = true;
                    Forward = false;
                    oRng.Find.Execute(ref FindText, ref missing, ref MatchWholeWord, ref missing, ref missing, ref missing, ref Forward,
                    ref missing, ref missing, ref ReplaceWith, ref missing, ref missing, ref missing, ref missing, ref missing);

                    oRng = oDoc.Range(ref missing, ref missing);
                    FindText = "[@FONE_ASSE]";
                    ReplaceWith = "Pajero";
                    oRng.Find.Execute(ref FindText, ref missing, ref MatchWholeWord, ref missing, ref missing, ref missing, ref Forward,
                    ref missing, ref missing, ref ReplaceWith, ref missing, ref missing, ref missing, ref missing, ref missing);
                    oApp.Visible = true;

                    FindText = "[@VENCTO]";
                    ReplaceWith = "azul";
                    MatchWholeWord = true;
                    Forward = false;
                    oRng.Find.Execute(ref FindText, ref missing, ref MatchWholeWord, ref missing, ref missing, ref missing, ref Forward,
                    ref missing, ref missing, ref ReplaceWith, ref missing, ref missing, ref missing, ref missing, ref missing);
                }
            }


            private void button3_Click(object sender, EventArgs e)
            {
                try

                {
                    WordFill clsWord = new WordFill();
                    clsWord.PreencherPorReplace(Application.StartupPath + "\\NOTIFICAÇÃO_EXTRAJUDICIAL_MODELO_ITAU1.docX");
                }
                    catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }

            }


    Esse é o erro:
    Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
    sábado, 7 de julho de 2012 21:28
  • O código acima dá erro no application e Documents. Veja meus using e o erro:

    using System;
    using System.ComponentModel;
    using System.Collections.Generic;
    using System.Data;
    using System.Text;
    using System.Configuration;
    using System.Windows.Forms;
    using MySql.Data.MySqlClient;
    using System.Data.OleDb;
    using Microsoft.Office.Interop.Word;

    Application application = new Application(); ==>> Erro no Application
    Document document = application.Documents.Open("C:\\word.doc"); ==>> Erro no Documents

                // Loop through all words in the document.
                int count = document.Words.Count;
                for (int i = 1; i <= count; i++)
                {
                    // Write the word.
                    string text = document.Words[i].Text;
                    Console.WriteLine("Word {0} = {1}", i, text);
                }
                // Close word.
                application.Quit(); ==>> Erro no Quit

    sábado, 7 de julho de 2012 21:37
  • Resolvi o erro assim:
    Microsoft.Office.Interop.Word.Application application = new Microsoft.Office.Interop.Word.Application();
    sábado, 7 de julho de 2012 21:44
  • Agora ele não substitui. Fiz esse código e mesmo assim, o arquivo não é substituido. E sempre que eu abro o arquivo me dá a seguinte mensagem:

    1.Deseja abrir o arquivo emmodo leitura?

    2. Deseja mesclar .....

    Esse é o código escrito:

    string nome = "NOME";

                // Loop through all words in the document.
                int count = document.Words.Count;
                for (int i = 1; i <= count; i++)
                {
                    if (nome == document.Words[i].Text)
                    {
                        nome.Replace("NOME", "Paulo");
                    }
                    // Write the word.
                    //string text = document.Words[i].Text;
                    //Console.WriteLine("Word {0} = {1}", i, text);
                }

    sábado, 7 de julho de 2012 22:07
  • Errei no método acima. Eu deveria substituir a string no word e não a variável. Bem, ela substitui no Debug, mas não salva e sempre faz a pergunta se quero abrir em modo leitura ou mesclar e eu não gostaria que essa mensagem apareça e que o documento fique salvo, pois virá do banco de dados dentro de um while a substituição das variáveis. Como proceder?

    Código correto:

    for (int i = 1; i <= count; i++)
                {
                    if (nome == document.Words[i].Text)
                    {
                        document.Words[i].Text = "Paulo";
                    }
                }

    sábado, 7 de julho de 2012 22:33
  • Olá pnet,

    Vou fazer alguns testes e te respondo.

    []s!


    Fernando Henrique Inocêncio Borba Ferreira
    while(alive){ this.WriteCode(); }
    Blog: http://ferhenriquef.com/
    Twitter: @ferhenrique
    Entity Framework - Brasil: https://www.facebook.com/EntityFrameworkBrasil

    domingo, 8 de julho de 2012 14:07
    Moderador
  • Olá Pnet,
    Tudo bem?

    Meu algoritmo ficou assim:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Word = Microsoft.Office.Interop.Word;
    namespace ConsoleApplicationWord
    {
        class Program
        {
            static void Main(string[] args)
            {
                WordReplace x = new WordReplace(@"C:\Users\Fernando\Desktop\replace - Copy.docx");
                x.Replace();
            }
        }
        public class WordReplace
        {
            private string _documentPath;
            public WordReplace(string documentPath)
            {
                this._documentPath = documentPath;
            }
            public void Replace()
            {
                
                Word.Application oApp = new Word.Application();
                Word.Document oDoc = oApp.Documents.Open(this._documentPath);
                ReplateString(oDoc, "[@NOME]", "Olá, enfermeira!");
                // Para não mostrar mensagens quando salvar ou qualquer outra mensagem
                oApp.ShowStartupDialog = false;
                // Salvando de verdade
                oDoc.Save();
                // Removendo o word da lista de processos em execução
                oDoc.Close();
                oApp = null;
            }
            private void ReplateString(Word.Document oDoc, string findText, string replaceText)
            {
                object missing = System.Reflection.Missing.Value;
                object FindText = findText;
                object ReplaceWith = replaceText;
                object MatchWholeWord = true;
                object Forward = false;
                
                Word.Range oRng = oDoc.Range(ref missing, ref missing);
                oRng.Find.Execute(ref FindText, ref missing, ref MatchWholeWord, ref missing, ref missing, ref missing, ref Forward,
                ref missing, ref missing, ref ReplaceWith, ref missing, ref missing, ref missing, ref missing, ref missing);
            }
        }
    }

    Pontos relevantes:
    - Encapsulei seu código de replace em um método, assim fica mais fácil dar manutenção
    - Ao invés de abrir o documento com um "Documents.Add" estou utilizando o "Documents.Open", é um processo mais "natural"
    - A propriedade ShowStartupDialog controla a exibição de mensagems de "Salvar", "Salvar Como", e outros.
    - O problema de abrir o documento e estar como somente leitura é pq estava falando fechar o documento e remover o processo da memória, o que foi resolvido com as linhas
    "oDoc.Close();" e "oApp = null;".

    Qualquer dúvida é só falar.

    []s!


    Fernando Henrique Inocêncio Borba Ferreira
    while(alive){ this.WriteCode(); }
    Blog: http://ferhenriquef.com/
    Twitter: @ferhenrique
    Entity Framework - Brasil: https://www.facebook.com/EntityFrameworkBrasil

    domingo, 8 de julho de 2012 14:49
    Moderador