我寫了下面的代碼,允許用戶查詢基於要打印的word文檔和數據源(不同系統)的數據,他們可以選擇SOURCE1,SOURCE2或BOTH。查詢數據,放入ODBC DataReader中,然後循環以填充ListView控件。從選定的Word文檔部分複製一個額外的空白頁面?
然後,我允許用戶選擇要打印的記錄,並將這些記錄作爲郵件合併操作處理到選定的Word文檔中。
我現在要做的是將每個單獨的文檔頁面(郵件合併的每個記錄)保存到具有自己名稱的特定文件夾位置。
CODE:
private void btnSearch_Click(object sender, EventArgs e)
{
lvData.Clear();
string qryCmd = "";
createColumns();
switch (cmbLetterType.SelectedIndex)
{
case 0:
qryCmd = chkSystem("oldAddr");
break;
case 1:
qryCmd = chkSystem("newAddr");
break;
case 2:
qryCmd = chkSystem("nameChg");
break;
}
// If the option for BOTH is selected, qryCmd is a long string containing the individual queries for SOURCE1 and SOURCE2.
// Here I check if a semicolon (;) exists, denoting that there are 2 cmd queries in the string.
// If so, I split the query calling GetiSeriesData() with the first query string, then assigning qryCmd the second
// strings value and continuing processing as normal.
if (qryCmd.Contains(";"))
{
char[] delimitChar = { ';' };
string[] splitQueries = qryCmd.Split(delimitChar);
qryCmd = splitQueries[0];
GetiSeriesData(qryCmd);
qryCmd = splitQueries[1];
}
GetiSeriesData(qryCmd);
// Display message if no records found.
if (lvData.Items.Count == 0)
{
MessageBox.Show("No records found.");
}
lblRecCnt.Text = lvData.Items.Count.ToString();
this.lvData.CheckBoxes = true;
}
public void GetiSeriesData(string query)
{
OdbcDataReader dr;
try
{
//Set value of system based on table being looked at in ConnectionString
string sysValue = "";
if (query.Contains("lib1"))
{
sysValue = "P";
}
if (query.Contains("lib2"))
{
sysValue = "N";
}
MergeDocLibrary mdl = new MergeDocLibrary();
dr = mdl.GetData(query);
Int16 x = 0;
string gndr = "";
// Fill ListView Control lvData
while (dr.Read())
{
lvData.Items.Add(dr["MEMNO"].ToString().Trim());
lvData.Items[x].SubItems.Add(dr["NAME"].ToString().Trim());
lvData.Items[x].SubItems.Add(dr["ADDR1"].ToString().Trim());
lvData.Items[x].SubItems.Add(dr["ADDR2"].ToString().Trim());
lvData.Items[x].SubItems.Add(dr["CITY"].ToString().Trim());
lvData.Items[x].SubItems.Add(dr["STATE"].ToString().Trim());
lvData.Items[x].SubItems.Add(dr["ZIP"].ToString().Trim());
lvData.Items[x].SubItems.Add(dr["OLD_ADDR1"].ToString().Trim());
lvData.Items[x].SubItems.Add(dr["OLD_ADDR2"].ToString().Trim());
lvData.Items[x].SubItems.Add(dr["OLD_CITY"].ToString().Trim());
lvData.Items[x].SubItems.Add(dr["OLD_STATE"].ToString().Trim());
lvData.Items[x].SubItems.Add(dr["OLD_ZIP"].ToString().Trim());
lvData.Items[x].SubItems.Add(sysValue.ToString().Trim());
lvData.Items[x].SubItems.Add(DateTime.Today.ToString("d"));
lvData.Items[x].SubItems.Add(dr["SEX"].ToString().Trim());
lvData.Items[x].SubItems.Add(dr["LNAME"].ToString().Trim());
if (dr["SEX"].ToString().Trim() == "M")
{
gndr = "Mr.";
}
else // (dr["SEX"].ToString().Trim() == "F)
{
gndr = "Ms.";
}
lvData.Items[x].SubItems.Add(gndr + dr["LNAME"].ToString().Trim());
lvData.Items[x].SubItems.Add(dr["CITY"].ToString().Trim() + ", " + dr["STATE"].ToString().Trim() + " " + dr["ZIP"].ToString().Trim());
x += 1;
}
mdl.closeConn();
}
catch (Exception ex)
{
MessageBox.Show("Source:\t" + ex.Source + "\nMessage: \t" + ex.Message + "\nData:\t" + ex.Data);
}
finally
{
}
}
public void OpenAndReview()
{
try
{
string docSave = @"C:\Users\NAME\Desktop\Test.doc";
//MergeDocLibrary mdl = new MergeDocLibrary();
//mdl.mergeDocument(docSource, docLoc);
// Original Mail Merge Document
Word.Range rng;
object start = 0;
object end = 0;
Word.Range newWrdRng;
Word.Application oWord = new Word.Application();
Word.Document oWrdDoc = new Word.Document();
// New Document Instance
Word.Application oNewWord = new Word.Application();
Word.Document oNewWrdDoc = new Word.Document();
// Set 'False' in PROD, 'True' in DEV
oWord.Visible = true;
oNewWord.Visible = true;
Object oTemplatePath = docLoc;
// Open Mail Merge Doc
oWrdDoc = oWord.Documents.Open(oTemplatePath);
// Open New Document
oNewWrdDoc = oNewWord.Documents.Open(docSave);
Object oMissing = System.Reflection.Missing.Value;
// Open Mail Merge Datasource
oWrdDoc.MailMerge.OpenDataSource(docSource, oMissing, oMissing, oMissing,
oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing);
// Execute Mail Merge
oWrdDoc.MailMerge.Execute();
// Set Mail Merge Document as Active Doc
//oWrdDoc.Activate();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
MessageBox.Show(oWord.ActiveDocument.Sections.Count.ToString());
// 3 Records selected gives 4 Sections Counted??
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Subtract 1 to account for the extra section being counted?
int docCnt = oWord.ActiveDocument.Sections.Count - 1;
int cnt = 0;
while (cnt != docCnt)
{
cnt++;
// Copy Desired Section from Mail Merge
oWord.ActiveDocument.Sections[cnt].Range.Copy();
// Set focus to the New Word Doc instance
oNewWord.Activate();
// Paste copied range to New Word Doc
oNewWord.ActiveDocument.Range(0, 0).Paste();
// Save New Word Doc
oNewWord.ActiveDocument.SaveAs2(@"C:\Users\NAME\Desktop\SuccesfullySavedDoc-" + cnt + ".doc");
// Clear New Word Doc
oNewWord.ActiveDocument.Content.Select();
oNewWord.Selection.TypeBackspace();
// Set Mail Merge as Active Document
oWord.Activate();
}
// .............
// Save new docuemnt...?
oNewWrdDoc.SaveAs2("SuccesfullySavedTest.doc");
}
catch (Exception ex)
{
MessageBox.Show("Source:\t" + ex.Source + "\nMessage: \t" + ex.Message + "\nData:\t" + ex.Data);
}
finally
{
//
}
}
...
EDIT3:我已經拿到了文件清理掉每個新的循環迭代。現在想弄清楚爲什麼每個文檔與一個額外的空白頁節省2
大致的輪廓:
文件1:記錄1 +一個額外的空白頁(不確定爲什麼?)
文檔2:記錄2 +一個額外的空白頁(不確定爲什麼?)
文件3:記錄3 +一個額外的空白頁(不確定爲什麼?)
順便說一句,如果你完全控制了文檔的內容/格式,你可以考慮使用Eric White的材料來生成這種輸出 - 它根本不使用MailMerge,更符合「 .NET的做事方式「 - http://ericwhite.com/blog/category/open-xml/document-generation-series/ – 2013-11-28 07:49:18
就我個人而言,我會考慮在保存後創建oNewWord文檔,創建一個新文檔,在你的循環裏面。我懷疑這是否會成爲主要的表現。 – 2013-12-02 16:33:33
這是一種選擇,但我更願意走這條路線(如果可能的話),只是爲了節省一點編碼,並保持對任何可能受到維護/更新路上遇到的獵物困擾的人的理解。 –