背景介紹
在進行word文檔Table目錄批量自動生成過程中,有個最討厭的環節就是有的文檔加密,這個時候通常就會跳出一個對話框讓你輸入密碼,但是這個就讓整個目錄生成流程編程了半自動的,對於大量的文檔目錄生成過程,這簡直是災難性的。現在需要自動識別文檔是否加密,對於加密的文檔直接跳過就好了。於是搜索了網上的一些材料,加上自己的實驗得到如下的解決方法:
總體思路:
1.設定隨意性的word文檔開啓密碼;
2.用Documents類的open方法打開word文檔(之前是使用add方法打開的,可是這樣就不能有下面的密碼錯輸觸發機制),由於使用了隨意性的密碼(比如“空格”),所以會導致文檔打開失敗消息發出;
3.文檔打開失敗的消息被try{}捕獲,交給catch{}處理,處理就是文檔關閉、指針釋放之類的操作,自動進行下一個文檔處理;
具體步驟的關鍵代碼如下:
1.參數定義:
COleVariant covTrue((short)TRUE),
covFalse((short)FALSE),
covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
COleVariant password(" ");
'''
特別注意password的定義,初始化是一個空格;
2.用Documents類的open方法打開word文檔
'''
doc.AttachDispatch(docs.Open(
COleVariant(strFilePath,VT_BSTR),
covFalse, // Confirm Conversion.
covFalse, // ReadOnly.
covFalse, // AddToRecentFiles.
password, // PasswordDocument.
covOptional, // PasswordTemplate.
covFalse, // Revert.
password, // WritePasswordDocument.
covOptional, // WritePasswordTemplate.
covOptional, // Format. // Last argument for Word 97
covOptional, // Encoding // New for Word 2000/2002
covTrue
) // Close Open parameters
); // Close AttachDispatch(?)
可見在“PasswordDocument”和“WritePasswordDocument”這兩個參數位置使用了參數password。
3.消息處理
當打開一個加密文檔之後,會被try{}捕獲密碼錯誤異常(除非恰好這個文檔的密碼就是空格),然後提交給catch{}處理,這個就不多說了,在程序裏面都有,下面把程序的代碼一段段粘貼上來。
(1)首先建立一個對話框,關於對話框內的內容就不多說了:
(2)新建一個對話框按鈕“製作索引”,表示開始進行Table抽取,按鈕雙擊後代碼:
void CMyDlgExDlg::OnBnClickedMakeTable()
{
// TODO: 在此添加控件通知處理程序代碼
GetDlgItem(IDC_TABLE_PATH)->GetWindowText(StrTableFilePath);
if(StrTableFilePath == "")
{
MessageBox("請輸入索引文件路徑");
return;
}
else
{
if(!MyTableFile.Open(StrTableFilePath,CFile::modeCreate|CFile::modeReadWrite,NULL))
{
MessageBox("打開文件操作失敗","信息提示",MB_OK);
}
else
{
//MessageBox(StrTableFilePath+"文件創建成功","信息提示",MB_OK);
FindFile(StrFolder);
m_bTableStop=FALSE;
MessageBox("目錄索引生成完畢","信息提示",MB_OK);
MyTableFile.Close();
}
}
}
(3)FindFile()函數
void CMyDlgExDlg::FindFile(CString MyPath)
{//查找文件
CString MyTempPath;
if(MyPath.Right(1)!="\\")
MyTempPath.Format("%s\\*.*",MyPath);
else
MyTempPath.Format("%s*.*",MyPath);
CFileFind MyFindFile;
BOOL bMyFind=MyFindFile.FindFile(MyTempPath);
while(bMyFind)
{
bMyFind=MyFindFile.FindNextFile();
CString cstemp=MyFindFile.GetFileName();
if(!MyFindFile.IsDots())
{
if(MyFindFile.IsDirectory())
FindFile(MyFindFile.GetFilePath());
else
{//提取table list
int i = 0;
CString strPath = MyFindFile.GetFilePath();
GetTable(strPath);
}
}
if(m_bTableStop)
return;
}
}
(4)GetTable()函數
void CMyDlgExDlg::GetTable(CString strFilePath)
{//建立索引文件
if( ((strFilePath.Find(".doc")>=0) || (strFilePath.Find(".docx")>=0))&&(strFilePath.Find("~$")<0))
{
/////////////////處理文檔////////////////////
//m_Path.SetWindowText(strPath); //顯示文件路徑
bool bReleased=false;
_Application app;
Documents docs,ndocs;
_Document doc,ndoc;
Range range,nrange;
Selection sel,nsel;
TablesOfContents tocs;
CString str ;
COleVariant covTrue((short)TRUE),
covFalse((short)FALSE),
covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
COleVariant password(" ");
CComVariant a (_T(strFilePath)),b(false),c(0),d(true),e(_T(""));
try
{
// CComVariant a (_T("d:\\test.docx")),b(false),c(0),d(true),e(_T(""));
//初始化連接
app.CreateDispatch("word.Application");
docs.AttachDispatch(app.GetDocuments());
doc.AttachDispatch(docs.Open(
COleVariant(strFilePath,VT_BSTR),
covFalse, // Confirm Conversion.
covFalse, // ReadOnly.
covFalse, // AddToRecentFiles.
password, // PasswordDocument.
covOptional, // PasswordTemplate.
covFalse, // Revert.
password, // WritePasswordDocument.
covOptional, // WritePasswordTemplate.
covOptional, // Format. // Last argument for Word 97
covOptional, // Encoding // New for Word 2000/2002
covTrue
) // Close Open parameters
); // Close AttachDispatch(?)
//doc.AttachDispatch(docs.Add(&a,&b,&c,&d));
sel.AttachDispatch(app.GetSelection());
range.AttachDispatch(sel.GetRange());
tocs.AttachDispatch(doc.GetTablesOfContents());
tocs.Add(range,&_variant_t(true),&_variant_t((long)1),&_variant_t((long)6)
,&_variant_t(false),&_variant_t(""),&_variant_t(true),&_variant_t(true)
,&_variant_t(""),&_variant_t(false),&_variant_t(false));
Paragraphs pgraphs;
pgraphs.AttachDispatch(doc.GetParagraphs());
CString szText = "";
long pgraphCount = pgraphs.GetCount();
str = strFilePath;
nFilesCnt++;
CString strNum;
strNum.Format("%d",nFilesCnt);
str= "\n\n\n\n=========== Files No : "+strNum+" ==========================================\n"+str;
MyTableFile.Write(str,::strlen(str)+1);
for (long i = 1; i<= pgraphCount; i++)
{
Paragraph pgraph;
pgraph.AttachDispatch(pgraphs.Item(i));
Range pragRange;
pragRange.AttachDispatch(pgraph.GetRange());
_ParagraphFormat format;
format.AttachDispatch(pragRange.GetParagraphFormat());
CComVariant value;
Style style;
value = format.GetStyle();
style.AttachDispatch(value.pdispVal);
CString szHeaderName = style.GetNameLocal();
char szName[10] = {0};
strncpy(szName, szHeaderName.GetBuffer(0), 6);
szHeaderName.ReleaseBuffer(0);
if (strcmp(szName, "目錄 1") != 0 && strcmp(szName, "目錄 2") != 0
&& strcmp(szName, "目錄 3") != 0)
{
sel.SetRange(0,i);
range.AttachDispatch(sel.GetRange());
str = range.GetText();
str += "\n";
MyTableFile.Write(str,::strlen(str)+1);
range.Cut();
nrange.AttachDispatch(doc.GetContent());
nrange.Paste();
i = pgraphCount + 1;
}
pgraph.ReleaseDispatch();
pragRange.ReleaseDispatch();
format.ReleaseDispatch();
style.ReleaseDispatch();
}
app.SetVisible(false);
app.Quit(&b,&c,&c);
range.ReleaseDispatch();
nrange.ReleaseDispatch();
doc.ReleaseDispatch();
docs.ReleaseDispatch();
app.ReleaseDispatch();
bReleased = true;
}
catch(...)
{
int iii=0;
if(!bReleased)
{
app.SetVisible(false);
app.Quit(&b,&c,&c);
range.ReleaseDispatch();
nrange.ReleaseDispatch();
doc.ReleaseDispatch();
docs.ReleaseDispatch();
app.ReleaseDispatch();
bReleased = true;
}
}
////////////////////處理文檔End//////////////////////////
}
}