将文本文件中的表格文本插入到 Microsoft Word 表格中






4.11/5 (2投票s)
将表格文本插入到 Microsoft Word 文档中。
简介
在我们的公司,我们有一个自动产品扫描仪,它读取设备的序列号(XXXX; XXXXS; XXXX,其中 X 是一个整数)并将其保存在一个表格文本文件中。
也许一个小时后,文本文件中会有超过 1000 个 SN 以表格格式保存。一天结束时,生产主管必须将扫描的 SN 的一部分插入 Microsoft Word 模板,然后他必须发送 PDF 副本给客户。
此工具可帮助生产主管将表格数据插入 Microsoft Word 文档,并将合并的文档转换为 PDF。
本项目提供了一个表格文本格式合并器,该合并器从给定的表格文本文件中复制数据,并在运行时将复制的文本插入/合并到给定的 Microsoft 文档表格中,最后将合并的 Microsoft Word 文档导出为 PDF 文件格式。
主窗体
主窗体的目的是控制应用程序的反馈,并允许用户以他们选择的任何方式运行它。当程序按图 3 所示运行时,您将看到浏览按钮和文本框。
第一个用于给定的表格文本文件。
第二个用于给定的 Microsoft Word 文档。
第三个是可选的,只是一个输出路径。
备注
- 用作模板的原始 Microsoft Word 文档。该工具不会更改原始文档文件,如果您想这样做,请设置
// object saveWordChanges = true;
- 在Config文件中,您可以定义给定 Microsoft Word 文档表格的开始索引。例如
// <add key="TableIndex" value="2" /> // <add key="RowIndex" value="2" />
- 该工具将打开给定的 Microsoft Word 原始文档中的第二个表格,然后跳转到第二行并开始写入复制的表格文本。
- 如果表格大小小于复制的表格文本大小,则用户将收到一个
TextInjector
格式错误。 - 如果复制的表格文本与给定的正则表达式不匹配,则用户将收到格式错误。
- 您可以定义需要从给定文本文件中复制多少列。
- 复制过程是逐个单元格进行的,起始单元格在Config文件中定义。
- Microsoft Word 2003 无法保存 PDF 格式,我已通过使用外部工具解决了此问题。
如何使用 TextInjector?
运行TextInjector
。
- 导航到表格文本文件,如图 3 所示。图 1 表格文本文件示例
- 导航到包含表格的 Microsoft Word 文档,如图 3 所示。图 2 Microsoft Word 文档示例
- 您需要浏览到所需的输出路径,如下面的图 3 所示。图 3 TextInjector
- 最后,单击“创建文件”按钮。PDF 文件将被创建,请参见图 4、5。图 4 创建的 PDF 文件图 5 测试目录
代码如何工作?
构造函数中调用的第一个方法是RetrieveAppSettings()
。
/// <summary>
/// Reads the settings from the Config file.
/// </summary>
private void RetrieveAppSettings()
{
var configurationAppSettings = new AppSettingsReader();
// the tabular Text file path
_inputTextFileTextBox.Text = (string)(configurationAppSettings.GetValue
("TextFilePath", typeof(string)));
// the Microsoft-Word document path
_inputWordFileTextBox.Text = (string)(configurationAppSettings.GetValue
("WordFilePath", typeof(string)));
…App.config 文件
<configuration>
<appSettings>
<add key="TextFilePath" value="C:\" />
<add key="WordFilePath" value="C:\" />
<add key="WordOutputPath" value="C:\" />
<add key="TextFilesFilter" value="txt files (*.txt)|*.txt" />
<add key="WordFilesFilter" value="txt files (*.doc)|*.doc" />
<add key="RegularExpressionFilter" value="^[0-9]{5}[- ;.]
[0-9]{5}S[- ;.][0-9]{4}$" />
<add key="NumberOfCloumnsInTextFile" value="3" />
<add key="RowSplitter" value=";" />
<add key="TableIndex" value="1" />
<add key="RowIndex" value="1" />
</appSettings>
</configuration>
此方法读取包含配置数据的应用程序App.config。每次导航到新路径时,新路径将写入App.config文件,如下所示
/// <summary>
/// Save the config data
/// </summary>
/// <param name="propertyName">App.config property name</param>
/// <param name="filePath">App.config file path.</param>
private static void SaveConfig(string propertyName, string filePath)
{
//open the configuration file for the current application
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
//set the value of the App.config property
config.AppSettings.Settings[propertyName].Value = filePath;
Causes only modified properties to be written to the configuration file,
even when the value is the same as the inherited value.
config.Save(ConfigurationSaveMode.Modified);
//----------------------------- here it’s funny----------------------
// You see the below two lines, the problem was:
// if I run the application from VS than I can’t save the
// configuration properties in the App.config
// This workaround for the problem
//var configFile = System.Windows.Forms.Application.StartupPath +
Path.DirectorySeparatorChar + ConfigFileName;
//config.SaveAs(configFile, ConfigurationSaveMode.Modified);
// Refreshes the named section so the next time that it is retrieved
// it will be re-read from disk.
ConfigurationManager.RefreshSection("appSettings");
}
应用程序已准备就绪。
CreateDocumentsButtonClick
是应用程序的核心方法,当用户单击“转换”按钮时调用它。
检查给定路径是否存在,如果找到任何错误,则返回
if (!File.Exists(_inputTextFileTextBox.Text))
{
MessageBox.Show("Input Text file doesn't exist!!");
return;
}
if (!File.Exists(_inputWordFileTextBox.Text))
{
MessageBox.Show("Input Word file doesn't exist!!");
return;
}
if (!Directory.Exists((_outputDocsPathTextBox.Text)))
{
MessageBox.Show("Output Word directory doesn't exist!!");
return;
}
从给定的表格文本文件中检索数据,如果发现格式错误并且用户取消了该过程,则返回
if (!RetrieveRows())
return;
下面我将解释最重要的代码部分
打开 Microsoft Word 文档并插入复制的表格。
表示 Microsoft Office Word 应用程序。
_Application wordApp = new Word.Application();
Microsoft Word 文档。
object wordFile = @_inputWordFileTextBox.Text;
虚拟对象。
object missing = Missing.Value;
文档将以只读模式打开。
object readOnly = true;
PDF 格式。
object fileFormat = WdSaveFormat.wdFormatPDF;
在这里,我获取了不带扩展名的 Microsoft Word 文档文件名。
var fileNameWithoutExt = Path.GetFileNameWithoutExtension(_inputWordFileTextBox.Text);
PDF 文件的名称与 Microsoft Word 文档的名称相同。
object wordPdfFile = _outputDocsPathTextBox.Text + Path.DirectorySeparatorChar +
fileNameWithoutExt + pdfExt;
wordApp.Documents
是当前在 Word 中打开的所有Microsoft.Office.Interop.Word.Document
对象的集合。wordApp.Documents.Open
在 Microsoft Word 应用程序中打开给定的 Microsoft Word 文档。
_Document wordDoc = wordApp.Documents.Open(ref wordFile,
ref missing, ref readOnly, ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing, ref missing, ref missing);
检查给定的 Microsoft Word 文档是否包含表格。
if (wordDoc.Tables.Count >= _tableIndex &&
wordDoc.Tables[_tableIndex].Rows.Count >= _rowIndex)
{
var destinationTable = wordDoc.Tables[_tableIndex];
object readOnlyRecommended = false;
for (var rowNrInList = 0; rowNrInList < _extractedRow.Count; rowNrInList++)
{
var row = _extractedRow[rowNrInList];
即时将表格文本插入到目标表格中。
for (var columnNrInList = 0; columnNrInList < row.Count; columnNrInList++)
{
//cell index begint with 1
destinationTable.Cell(rowNrInList +1, columnNrInList+1).Range.Text =
row[columnNrInList];
}
将修改后的文档导出为 PDF。
wordDoc.SaveAs(ref wordPdfFile, ref fileFormat,
ref missing, ref missing, ref missing,
ref missing, ref readOnlyRecommended,
ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing);
RetrieveRows()
从CreateDocumentsButtonClick()
调用以读取文本数据。
- 从表格文本文件中提取数据。
- 检查提取的行是否与给定的正则表达式匹配。
- 将结果添加到 _
rowTextLine
。 - 如果过程无错误完成,则返回
true
。
/// <summary>
// Retrieves the data from the given tabular text file.
// </summary>
// <returns>True, if no format error found. </returns>
private bool RetrieveRows()
{
//clear old data
_extractedRow.Clear();
//return flag
var readSuccessfullyCompleted = true;
//regular Expression pattern
var formatRegex = new Regex(_regularExpressionText);
//read the text file
var fileText = File.ReadAllText(_inputTextFileTextBox.Text);
//split the tabular text file in lines
_rowTextLine = new List<string>(fileText.Split(new[] { Environment.NewLine },
StringSplitOptions.RemoveEmptyEntries));
//for each line
foreach (var row in _rowTextLine)
{
//if the line matched the regualr expression
if (formatRegex.IsMatch(row))
{
//split the row depending on the _rowSplitter char which is
//given in the Config file.
var rowSpiltter = row.Split(_rowSplitter);
//add to row
_extractedRow.Add(new List<string>(rowSpiltter));
}
else
{
//error message
var dlgResult = MessageBox.Show("Format error founded in the
tabular text file!",
"Continue?", MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
if (dlgResult == DialogResult.No)
{
readSuccessfullyCompleted = false;
break;
}
}
return readSuccessfullyCompleted;
}
历史
- 2010 年 8 月 26 日:初始帖子