目前做金融業的項目,該公司每天會產生很多 Word、Excel 文檔,需要大量地轉換為 PDF,除了自己保存外,也要給金融主管機構作為備份。由于文檔數量很多,希望有工具能在下班前、作完設置后,放著讓機器自動、大量地批轉;除此之外,亦希望有特殊的功能,例如給主管機構的 Excel 文檔,能僅選擇其中某幾個 sheet (工作表) 轉成 PDF。 我找了網絡上許多 PDF 轉換工具,沒有完全符合上述需求的,只好自己用 .NET / VSTO 寫一個。
開發環境:
(1) VS 2008 / Windows Form / VB.NET / VSTO
(2) Office 2007 或 Office 2010 或更高版本 (需要引用新版 Office 里的 COM 組件)
(3) 2007 Microsoft Office 加載項:Microsoft Save as PDF 或 XPS (可將 Office 2007 或更高版本的文件,導出成 PDF 或 XPS 文件)
執行環境:
(1) .NET Framework
(2) Office 2007 或 Office 2010 或更高版本 (舊版的 Office XP / Office 2003 不行)
(3) 2007 Microsoft Office 加載項:Microsoft Save as PDF 或 XPS (可將 Office 2007 或更高版本的文件,導出成 PDF 或 XPS 文件)
特性:
(1) 支持中文文件名 (免費的 PDFCreator 從 1.2.x 版后即不支持)、中文目錄、中文命名的 sheet。
(2) 可選擇 Excel 的某一個或某幾個 sheet,整合轉換成「單一個」PDF (Adobe Acrobat Standard 亦無此功能,要很貴的 Adobe Acrobat Professional 才有)。
(3) 可選擇 Excel 的某一個或某幾個 sheet,「各自」轉換成一個 PDF (我在網絡上未找到具備此功能的軟件)。
(4) 批轉的速度很快,大量批轉時亦不曾發生程序崩潰,或占據 Word、Excel 文件資源不釋放的情形。
(5) 可處理 Excel 里,整個 sheet 內容全為空白的不正常情形。
-------------------------------------------------
本帖的示例下載點:
https://files.cnblogs.com/WizardWu/120930.zip
附源碼。若需要簡體中文介面的網友,請自行用 VS 開啟項目后,改寫及編譯。
---------------------------------------------------
| 執行畫面 |
圖 1 直接雙擊 .exe 執行
圖 2 分為兩大功能
| 功能一 - 大批文件轉換 |
圖 3 功能一,批轉多個目錄里的 Word、Excel 文檔 - 轉換前
圖 4 功能一,批轉多個目錄里的 Word、Excel 文檔 - 轉換后
關鍵代碼 (大批文件轉換)
''' Word 轉 PDF
''' </summary>
''' <param name="PathAndFileName">路徑名\檔名.副檔名</param>
Public Sub ConvertWordToPDF(ByVal PathAndFileName As String)
Dim mstrResultFormPath As String = PathAndFileName
Dim strPDFFileName As String = Path.ChangeExtension(mstrResultFormPath, ".pdf")
Dim docApp As Object = CreateObject("Word.Application")
Dim docDoc As Object = docApp.Documents.Open(mstrResultFormPath)
Try
'ExportFormat: 指定要以 PDF 還是 XPS 格式儲存文件
docDoc.ExportAsFixedFormat(OutputFileName:=strPDFFileName, ExportFormat:=17)
Catch ex As Exception
Throw New Exception("轉換 Word 檔 " & PathAndFileName & " 時發生錯誤,錯誤為:" & ex.Message)
Finally
docApp.Documents.Close()
docApp.Quit()
End Try
End Sub
''' <summary>
''' Excel 轉 PDF (可有空白 sheet)
''' </summary>
''' <param name="PathAndFileName">路徑名\檔名.副檔名</param>
Public Sub ConvertExcelToPDF(ByVal PathAndFileName As String)
'Dim ws As Excel.Worksheet
Dim mstrResultFormPath As String = PathAndFileName '例:d:\excelTestPDF.xls
Dim strPDFFileName As String = Path.ChangeExtension(mstrResultFormPath, ".pdf")
Dim xlsApp As Object = CreateObject("Excel.Application")
Dim xlsWBook As Object = xlsApp.Workbooks.Open(mstrResultFormPath)
Try
xlsWBook.ExportAsFixedFormat(Type:=0, Filename:=strPDFFileName, IgnorePrintAreas:=False, OpenAfterPublish:=False, IncludeDocProperties:=True, Quality:=Excel.XlFixedFormatQuality.xlQualityStandard)
Catch ex As Exception
Throw New Exception("轉換 Excel 檔 " & PathAndFileName & " 時發生錯誤,錯誤為:" & ex.Message)
Finally
xlsApp.Workbooks.Close()
xlsApp.Quit()
End Try
End Sub
| 功能二 - Excel 特定 sheet 轉換 |
圖 5 功能二,可選擇 Excel 的某一個或某幾個 sheet,整合轉換成「單一個」PDF
關鍵代碼 (Excel 的某一個或某幾個 sheet,整合轉換成「單一個」PDF)
Public Sub ConvertCheckedSheetToOnePDF(ByVal PathAndFileName As String, ByVal listChecked As List(Of String), ByVal listUnChecked As List(Of String))
Dim oExcel As New Excel.Application
Dim oBooks As Excel.Workbooks, oBook As Excel.Workbook
Dim oSheets As Excel.Sheets
'Dim oSheet As Excel.Worksheet
Dim sTemplate As String, sFileName As String
'Excel 檔路徑
sTemplate = PathAndFileName
'捉路徑+檔名(不含副檔名)
sFileName = PathAndFileName.Substring(0, PathAndFileName.LastIndexOf("."))
oExcel.Visible = False
oExcel.DisplayAlerts = False
oBooks = oExcel.Workbooks
oBooks.Open(sTemplate)
oBook = oBooks.Item(1)
oSheets = oBook.Worksheets
'將沒勾選的 Worksheet,從 Workbook 裡移除
If Not listUnChecked Is Nothing Then
If listUnChecked.Count > 0 Then
Dim sheetDelete As Excel.Worksheet = Nothing '暫存用
For Each s_unC In listUnChecked
'oBook.Sheets(s_unC).Delete() '這種寫法,會引發: 無效的索引 (發生例外狀況於 HRESULT: 0x8002000B (DISP_E_BADINDEX」
sheetDelete = oBook.Sheets(s_unC) '依 sheet 的中文名稱,作為移除的依據
If Not sheetDelete Is Nothing Then
sheetDelete.Delete()
End If
sheetDelete = Nothing
Next
End If
End If
oBook.ExportAsFixedFormat(Type:=Excel.XlFixedFormatType.xlTypePDF, Filename:=sFileName & ".pdf", Quality:=Excel.XlFixedFormatQuality.xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=False)
圖 6 功能二,可選擇 Excel 的某一個或某幾個 sheet,「各自」轉換成一個 PDF
關鍵代碼 (Excel 的某一個或某幾個 sheet,「各自」轉換成一個 PDF)
Public Sub ConvertCheckedSheetToMultiplePDF(ByVal PathAndFileName As String, ByVal listChecked As List(Of String))
Dim oExcel As New Excel.Application
Dim oBooks As Excel.Workbooks, oBook As Excel.Workbook
Dim oSheets As Excel.Sheets
Dim oSheet As Excel.Worksheet
Dim sTemplate As String, sFileName As String
' Excel 檔路徑
sTemplate = PathAndFileName
'捉路徑+檔名(不含副檔名)
sFileName = PathAndFileName.Substring(0, PathAndFileName.LastIndexOf("."))
oExcel.Visible = False
oExcel.DisplayAlerts = False
oBooks = oExcel.Workbooks
oBooks.Open(sTemplate)
oBook = oBooks.Item(1)
oSheets = oBook.Worksheets
For i As Integer = 0 To listChecked.Count - 1
ProgressBar1.PerformStep() '進度列
'ss &= listChecked(i) & vbCrLf
oSheet = CType(oSheets.Item(listChecked(i)), Excel.Worksheet)
'ss &= oSheet.Name & vbCrLf
oSheet.ExportAsFixedFormat(Excel.XlFixedFormatType.xlTypePDF, IncludeDocProperties:=True, OpenAfterPublish:=False, Quality:=Excel.XlFixedFormatQuality.xlQualityStandard, _
Filename:=sFileName & "_" & oSheet.Name & ".pdf")
Next
| 組件引用 |
圖 7 Office 2007 開發環境。項目需要手動引用三個組件
如上圖 7,VS 里需要自行引用 Microsoft Office.Tools.Excel、Microsoft Office.Tools.Word 兩個 .NET 組件,以及 Microsoft Excel Object Library 這個 Office 里的 COM 組件。 但需注意,在開發環境中若安裝的是 Office 2007,則可引用的 Microsoft Excel Object Library 版本為 1.5 版 (11.0) 或 1.6 版 (12.0),此時編譯的程序,可拿至安裝 Office 2007 及 Office 2010 的用戶機器上執行;但若如下圖 8,在開發環境中安裝的是 Office 2010,則可引用的 Microsoft Excel Object Library 版本為 1.7 版 (14.0),此時編譯的程序,就只能拿至安裝 Office 2010 的用戶機器上執行,若拿至安裝 Office 2007 的用戶機器上會無法執行。
圖 8 Office 2010 開發環境。項目需要手動引用三個組件
| 結論 |
此種轉換功能,亦可寫成 ASP.NET 網頁介面,但不建議。因轉化動作極耗系統資源,若大量批轉容易造成 IIS 死機,且 IIS_WPG、Network Service 群組默認的權限不足,需要另外處理權限、安全性的設置。
參考文章:
Word 及 Excel 的 Workbook.ExportAsFixedFormat Method
http://msdn.microsoft.com/zh-cn/library/microsoft.office.tools.excel.workbook.exportasfixedformat.aspx
http://msdn.microsoft.com/zh-cn/library/microsoft.office.tools.word.document.exportasfixedformat.aspx
http://msdn.microsoft.com/en-us/library/office/bb238907%28v=office.12%29.aspx
如何給excel新增工作表 C# (Worksheet 操作大全)
http://topic.csdn.net/u/20080623/14/d47504a2-086b-4449-bffb-4f9ae6b62eb4.html
ASP.NET 產生 PDF 或 XPS 檔 (繁體中文)
http://teacher.syset.com/viewtopic.mspx?t=3911
ASP.NET 產生 PDF 或 XPS 檔 (繁體中文)
http://www.dotblogs.com.tw/rainmaker/archive/2010/01/25/13275.aspx
Merge Workbook With Another Workbook using VSTO
http://social.msdn.microsoft.com/forums/en-US/vsto/thread/85a3dac8-b32a-443a-8601-4e95935fe368
Printing multiple worksheets as seperate PDF files
http://www.mrexcel.com/forum/excel-questions/646486-printing-multiple-worksheets-seperate-pdf-files.html
http://en.allexperts.com/q/Excel-1059/2010/4/converting-worksheets-workbook-separate.htm
ASP.NET調用COM Word轉Pdf之我見
http://www.haogongju.net/art/1055828
Print To PDF Using Microsoft's PDF/XPS Add-in
http://www.excelguru.ca/content.php?170-Print-To-PDF-Using-Microsoft-s-PDF-XPS-Add-in
http://www.excelguru.ca/content.php?161
How do I export multiple sheets/charts to a single PDF, but not the entire workbook ? (此做法有缺陷)
http://social.msdn.microsoft.com/Forums/pl-PL/exceldev/thread/7b16b912-5356-4c3c-b517-6f1c91d26d72
VSTO 入門 (Visual Studio Tools for Office)
http://msdn.microsoft.com/zh-cn/library/23cw517s%28v=vs.80%29.aspx
參考書籍:
Visual Studio Tools for Office 2007
http://www.silverlightchina.net/html/download/books/2010/1008/2473.html
相關文章:
利用Office Save as PDF or XPS 實現Office批傳PDF
http://www.rzrgm.cn/mecity/archive/2011/06/23/2087973.html
Convert Word-Documents to PDF on an ASP.NET Server
http://www.codeproject.com/Articles/38592/Convert-Word-Documents-to-PDF-on-an-ASP-NET-Server
Excel VBA - WorkSheet新增、複製、刪除(不出現提示視窗)
http://tgw1029.blogspot.tw/2010/01/excel-vba-worksheet.html
http://msdn.microsoft.com/en-us/library/microsoft.office.tools.excel.worksheet.copy%28VS.80%29.aspx

浙公網安備 33010602011771號