避免合并文档中的换行

时间:2014-12-15 17:59:46

标签: c# ms-word office-interop font-size linewrap

我有这个程序,我写的是为我公司的仓库创建bin标签。每个季节,我们都会打印几百个标签。

我遇到的问题是,在模板中使用的字体大小,有时线条包裹,然后事情更难阅读或不适合标签等等。所以我最终通过生成合并文档,并手动减少行换行的各行的字体大小。这是一个真正的痛苦。

我真正想要做的是,对于给定字段的内容,将字体大小设置为等于或小于模板中使用的字体大小的最大大小,以防止换行。但我无法弄清楚如何实现这一目标。

这可能是一个不常见的问题?当然,我有一些明显的解决方案,我不知道?

如果没有别的,我想我可能会使用一个将行长度映射到字体大小的字典,我只是通过反复试验来提出。但似乎必须有一些更好的方法不会向我跳出来,那些对Word互操作有更多经验的人可能会指出我。

这是我的代码:

    /// <summary>
    /// Creates a mail merge document from a template and some data.
    /// </summary>
    /// <param name="templatePath">
    ///   The path (including the pathname) of the template file to open.
    /// </param>
    /// <param name="mergedFilePath">
    ///   The path (including the pathname) to save the resulting merged file to
    /// </param>
    /// <param name="mergeData">
    ///   The data to use for the merge - An array of Dictionaries that map strings to strings; 
    ///   the keys are template field names and the values are the field values to use.
    /// </param>
    public void Create(string templatePath, string mergedFilePath, DataTable mergeData){
        Object oMissing = System.Reflection.Missing.Value;

        // start up word and start reporting progress
        Word.Application wordApp = new Word.Application();
        ProgressStarted("Creating merge document..", mergeData.Rows.Count);  

        Thread thread = new Thread(() => {

            try {
                // copy the template file to the target file (for the sake of the layout properties)
                if (File.Exists(mergedFilePath)) {
                    File.Delete(mergedFilePath);
                }
                File.Copy(templatePath, mergedFilePath);

                // open the template, the target document, and a (new) temporary document (that will never be saved)
                Word.Document templateDoc = wordApp.Documents.Add(templatePath, oMissing, oMissing, oMissing);
                Word.Document mergedDoc = wordApp.Documents.Add(mergedFilePath, oMissing, oMissing, oMissing);
                Word.Document tempDoc = wordApp.Documents.Add(oMissing, oMissing, oMissing, oMissing);

                // clear out the target document (to start with)
                mergedDoc.Activate();
                mergedDoc.Content.Text = "";

                // iterate through the rows in mergeData
                int rowNum = 0;
                while (rowNum < mergeData.Rows.Count) {

                    // copy the template document into the temporary document
                    tempDoc.Content.FormattedText = templateDoc.Content.FormattedText;

                    // replace the text in the merge fields in the temporary document
                    foreach (Word.Field mergeField in tempDoc.Fields) {

                        // the field text comes in the format " MERGEFIELD  {fieldname} " (without the quotes or curly braces)
                        Word.Range rngFieldCode = mergeField.Code;
                        String[] fieldText = rngFieldCode.Text.Trim().Split((char[])null, StringSplitOptions.RemoveEmptyEntries); // null parameter means "use whitespace as a delimiter"
                        if (rowNum < mergeData.Rows.Count) {
                            if (fieldText[0] == "MERGEFIELD") {
                                string fieldName = fieldText[1];
                                string fieldValue = mergeData.Rows[rowNum][fieldName].ToString();

                                System.Diagnostics.Debug.WriteLine(string.Format("field: {0}  value: {1}", fieldName, fieldValue));

                                mergeField.Select();
                                wordApp.Selection.TypeText(fieldValue);     // type the value into the field
                            }
                            else if (fieldText[0] == "NEXT") {
                                rowNum += 1;
                                ProgressMade(rowNum);           // (invoked progress display update)
                                mergeField.Code.Text = "";      // blank out where it says "<<next record>>"
                            }
                        }
                        else {
                            mergeField.Code.Text = "";          // blank out the remaining fields after we run out of data
                        }
                    }

                    // add the contents of the temporary document into the target document
                    mergedDoc.Content.Select();
                    wordApp.Selection.Collapse(Word.WdCollapseDirection.wdCollapseEnd);
                    wordApp.Selection.InsertXML(tempDoc.Content.XML);
                    tempDoc.Content.Text = "";

                    // if we're not done yet, insert a page break
                    if (rowNum < mergeData.Rows.Count) {
                        mergedDoc.Content.Select();
                        wordApp.Selection.Collapse(Word.WdCollapseDirection.wdCollapseEnd);
                        wordApp.Selection.InsertBreak();
                        wordApp.Selection.InsertXML(tempDoc.Content.XML);
                    }
                }

                // delete the last empty paragraph (hopefully this will eliminate any dangling empty page)
                Word.Paragraph emptyPara = null;
                foreach (Word.Paragraph para in mergedDoc.Paragraphs) {
                    if (para.Range.Text.Trim() == String.Empty) {
                        emptyPara = para;
                    }
                }
                if (emptyPara != null) {
                    emptyPara.Range.Select();
                    wordApp.Selection.Delete();
                }

                // save the merged document
                mergedDoc.SaveAs(mergedFilePath);

                //mergedApp.Documents.Open(mergedFilePath);

                // close and release the documents
                ((Word._Document)tempDoc).Close(Word.WdSaveOptions.wdDoNotSaveChanges);
                ((Word._Document)mergedDoc).Close(Word.WdSaveOptions.wdDoNotSaveChanges);
                ((Word._Document)templateDoc).Close(Word.WdSaveOptions.wdDoNotSaveChanges);
                System.Runtime.InteropServices.Marshal.ReleaseComObject(tempDoc);
                System.Runtime.InteropServices.Marshal.ReleaseComObject(mergedDoc);
                System.Runtime.InteropServices.Marshal.ReleaseComObject(templateDoc);
                tempDoc = null;
                mergedDoc = null;
                templateDoc = null;
            }
            catch (Exception exc) {
                System.Diagnostics.Debug.WriteLine("error: " + exc.Message);
                Error(exc); // (invoked error dialog)
            }
            finally {
                // quit the application and and perform garbage collection
                ((Word._Application)wordApp.Application).Quit();
                wordApp = null;
                GC.Collect();
                // signal that we're done
                System.Diagnostics.Debug.WriteLine("Signaling progress finished");
                ProgressFinished(); 
            }
        });
        thread.Start();
    }

0 个答案:

没有答案