我有这个程序,我写的是为我公司的仓库创建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();
}