Как найти и заменить в списке, используя interop.word? - PullRequest
0 голосов
/ 21 февраля 2020

Поэтому я пытаюсь собрать код для замены определенных уникальных предложений в список для каждого типа флажка checkbox.check, например:

"uniquecode1" в:

  • Элемент списка 1
  • Элемент списка 2

Мне удалось использовать простой метод поиска и замены из c# взаимодействия слов, найти и заменить все Но у меня все еще нет не нашел способ конвертировать их в элемент списка. В какой-то момент я подумал, почему бы мне не сделать это таким образом?

for (int i = 0; i == checkedbox.Count; i++)
            {
                FindAndReplace(oWord, "uniquecode1", checkedbox[i]);
            }

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

string[] Mycollection = new string[] { "One, Two, Three" };
            string temp;
            SaveFileDialog saveFileDialog1 = new SaveFileDialog();

            saveFileDialog1.Filter = "pdf files (*.pdf)|*.pdf";
            saveFileDialog1.FilterIndex = 2;
            saveFileDialog1.RestoreDirectory = true;
            saveFileDialog1.ShowDialog();
            temp = saveFileDialog1.FileName;

            // Create an instance of Word.exe
            Microsoft.Office.Interop.Word.Application oWord = new Word.Application
            {
                // To make this instance of word invisible (Can still see it in the taskmgr).
                Visible = false
            };

            // Interop requires objects.
            object oMissing = System.Reflection.Missing.Value;
            object isVisible = true;
            object readOnly = true;     // Does not cause any word dialog to show up
            //object readOnly = false;  // Causes a word object dialog to show at the end of the conversion
            object oInput = textBox1.Text;
            object oOutput = temp;
            object oFormat = WdSaveFormat.wdFormatPDF;

            // Load a document into our instance of word.exe
            Document oDoc = oWord.Documents.Open(
                ref oInput, ref oMissing, ref readOnly, ref oMissing, ref oMissing,
                ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing,
                ref oMissing, ref isVisible, ref oMissing, ref oMissing, ref oMissing, ref oMissing
                );

            // Make this document the active document.
            oDoc.Activate();
            //Replace Text1
            FindAndReplace(oWord, "<Input Module1>", richTextBox1.Text);
            //Replace Text to List1
            foreach(string lisText in Mycollection)
            {
                //program to convert Text into a bullet or number list
            }

                // Save this document using Word
                oDoc.SaveAs(ref oOutput, ref oFormat, ref oMissing, ref oMissing,
                ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing,
                ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing
                );

            // Always close Word.exe.
            oWord.Quit(ref oMissing, ref oMissing, ref oMissing);

Согласно Sauntinsoft, они использовали

string loadPath = @"..\..\example.docx";

            DocumentCore dc = DocumentCore.Load(loadPath);
            string[] myCollection = new string[] { "One", "Two", "Three", "Four", "Five" };

            ListStyle bullList = new ListStyle("Bullets", ListTemplateType.Bullet);
            dc.Styles.Add(bullList);
            int level = 0;

            List<Paragraph> parList = new List<Paragraph>();


            foreach (string listText in myCollection)
            {
                Paragraph p = new Paragraph(dc);
                p.Content.End.Insert(listText, new CharacterFormat() { Size = 14.0, FontColor = Color.Black });
                p.ListFormat.Style = bullList;
                p.ListFormat.ListLevelNumber = level;
                p.ParagraphFormat.SpaceAfter = 0;
                parList.Add(p);
            }

            Regex regex = new Regex(@"Hello", RegexOptions.IgnoreCase);


            foreach (ContentRange item in dc.Content.Find(regex).Reverse())
            {
                foreach (Paragraph p in parList.Reverse<Paragraph>())
                    item.End.Insert(p.Content);               
            }

            foreach (ContentRange item in dc.Content.Find(regex).Reverse())
            {
                item.Delete();
            }
            string savePath = Path.ChangeExtension(loadPath, ".replaced.docx");
            dc.Save(savePath, SaveOptions.DocxDefault);

            // Open the original and result documents for demonstration purposes.
            System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(loadPath) { UseShellExecute = true });
            System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(savePath) { UseShellExecute = true });

1 Ответ

1 голос
/ 24 февраля 2020

Выполнение с помощью взаимодействия - многоэтапный процесс. Сначала необходимо найти цель - текст, который ищется. Затем вставьте информацию в этот Range и, наконец, отформатируйте ее.

Word's Find.Execute возвращает логическое значение - в случае успеха это true, и Range, на котором запускается Find, находится в найденное место. Поэтому добавьте текст к Range, затем отформатируйте его Range, как показано в примере кода *:

Word.Document doc = wdApp.ActiveDocument;
//Code from question
//Document oDoc = oWord.Documents.Open(
//            ref oInput, ref oMissing, ref readOnly, ref oMissing, ref oMissing,
//            ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing,
//            ref oMissing, ref isVisible, ref oMissing, ref oMissing, ref oMissing, ref oMissing);

Word.Range rng = doc.Content;
Word.Find f = rng.Find;
object oTrue = true;
object missing = Type.Missing;

string searchTerm = "uniquecode1";

f.ClearFormatting();
f.Text = searchTerm;
bool found = f.Execute(ref missing, ref missing, ref missing, ref missing, ref missing, ref missing,
    ref missing, Word.WdFindWrap.wdFindStop, ref missing, ref missing, Word.WdReplace.wdReplaceNone,
    ref  missing, ref missing, ref missing, ref missing);
if (found)
{
    rng.Delete();
    //Code from question
    //for (int i = 0; i == checkedbox.Count; i++)
    List<string> lst = new List<string> { "one", "two", "three" };
    foreach (string entry in lst)
    {
        rng.InsertAfter(entry + "\n");
    }
    rng.ListFormat.ApplyBulletDefault();
}

* Учитывая требования как I чтобы понять их в вопросе, это можно сделать полностью, используя Find & Replace , если :

  • Replacement.Text может быть одной строкой . В этом примере это было бы возможно путем объединения всех значений в одну строку до Find и присвоения этой строке f.Replacement.Text. Тогда параметр Word.WdReplace.wdReplaceNone будет иметь значение wdReplaceOne.
  • Пули / нумерация определяются как именованный стиль . Для этого потребуется стиль абзаца в документе (или динамически сгенерированный кодом), который ссылается на объект ListTemplate, который определяет маркер и / или нумерацию. Предполагая, что это присутствует, стиль может быть назначен на Replacement.set_Style("stylename");, а затем параметр Format должен быть установлен на true.

Это по сути то, что происходит за кулисами с библиотека, за которую вы не хотите платить.

...