用Microsoft.Office.Interop.Excel和CLR在Python中打印Excel文件?

我一直在寻找很多方法来打印excel文件,而不打开Excel应用程序 ,我在C#中使用Microsoft.Office.Interop.Excel,它工作得很好,所以我决定寻找一种方法,使其在Python中工作,我发现IronPython,但我只需要python,然后我发现pythonnet使.NET程序集在python中工作。

问题是,从源https://github.com/pythonnet/pythonnet安装它(或试图)它给了我一个关于Windows SDK找不到或错误的错误。

然后我用pip安装它,安装成功,但是当我尝试导入或添加引用时,显示另一个错误:

Unable to find assembly 'Microsoft.Office.Interop.Excel'. at Python.Runtime.CLRModule.AddReference(String name) 

我已经从这里下载并安装了Interop Assemblies,所以他们应该被安装。

我发现了一个在这里使用IronPython和Interop dll打印excel文件的方法。

我的主要问题是我需要打印一些Excel文件,而不打开Excel应用程序 ,如果你有另一个选项是值得欢迎的

如果没有其他select,我该怎么做才能find组件?


附加信息:用C#打印我用这个:

 Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application(); String CompletePath = path; Microsoft.Office.Interop.Excel.Workbook wb = excelApp.Workbooks.Open(CompletePath, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); Microsoft.Office.Interop.Excel.Worksheet ws = (Microsoft.Office.Interop.Excel.Worksheet)wb.Worksheets[1]; try { // Open the Workbook: // Get the first worksheet. // (Excel uses base 1 indexing, not base 0.) ws.PageSetup.Orientation = Microsoft.Office.Interop.Excel.XlPageOrientation.xlLandscape; ws.PageSetup.FitToPagesTall = 1; ws.PageSetup.FitToPagesWide = 1; ws.PageSetup.TopMargin = 0; ws.PageSetup.HeaderMargin = 0; ws.PageSetup.RightMargin = 0; ws.PageSetup.LeftMargin = 0; ws.PageSetup.BottomMargin = 0; ws.PageSetup.FooterMargin = 0; ws.PageSetup.CenterVertically = true; ws.PageSetup.CenterHorizontally = true; //ws.PageSetup.Zoom = false; ws.PrintOut(Type.Missing, Type.Missing, Type.Missing, Type.Missing, PrinterName, Type.Missing, Type.Missing, Type.Missing); return true; } catch (Exception ex) { LogSystem.TextLog.create(); LogSystem.TextLog.Write("ERROR ", LogSystem.ErrorType.Error, DateTime.Now, ex.Message); return false; } finally { // Cleanup: GC.Collect(); GC.WaitForPendingFinalizers(); System.Runtime.InteropServices.Marshal.FinalReleaseComObject(ws); wb.Close(false, Type.Missing, Type.Missing); System.Runtime.InteropServices.Marshal.FinalReleaseComObject(wb); excelApp.Quit(); System.Runtime.InteropServices.Marshal.FinalReleaseComObject(excelApp); } 

虽然我相信有一种使用win32com.client自动化Excel的方法( 有一个很好的例子 ),用.net包装com互操作代码并使用Python.Net公开它可能是有用的。 .net的考虑可能是com互操作的更好的支持和简单性,但是你应该考虑到Python.Net本身并不完善,并没有积极地发展多年。

接下来的方法是:

  1. 使用.net编写代码,并尽可能使用简单的接口公开此代码
    避免暴露COMtypes!
    避免pipe理一个国家!
  2. 从python消费图书馆。

步骤1

  • 创build名为ExcelToolsLibrary的新的.Net ClassLibrary项目
  • 添加对Microsoft.Office.Interop.Excel的引用
  • 放置下一个代码:

     namespace ExcelTools { using System; using Microsoft.Office.Interop.Excel; public class ExcelPrinter { public bool PrintFile(string fileName, string printerName) { var excel = new Application(); var workbook = excel.Workbooks.Open(fileName); var worksheet = (Worksheet)workbook.Worksheets[1]; try { SetupPage(worksheet); worksheet.PrintOut(ActivePrinter: printerName ?? Type.Missing); workbook.Close(false); return true; } catch (Exception ex) { LogError(ex); return false; } finally { DisposeExcelObjects(excel,worksheet,workbook); } } private void SetupPage(Worksheet worksheet) { worksheet.PageSetup.Orientation = XlPageOrientation.xlLandscape; //put additional page setup here } private void LogError(Exception e) { //add your logging } private void DisposeExcelObjects(Application excelApp,params object[] comObjects) { try { foreach (var obj in comObjects) System.Runtime.InteropServices.Marshal.FinalReleaseComObject(obj); excelApp.Quit(); System.Runtime.InteropServices.Marshal.FinalReleaseComObject(excelApp); } catch (Exception e) { LogError(e); } } } } 

第2步

在python中使用这个库:

  • 生成项目并将ExcelToolsLibrary.dll从输出放置到path中的任何位置(可以使用.pth文件 )。
  • 导入库并像这样使用它:

     import clr clr.AddReference("ExcelToolsLibrary") # 'ExcelToolsLibrary' is a dll name without the path import ExcelTools # 'ExcelTools' is a .Net namespace printer = ExcelTools.ExcelPrinter() printer.PrintFile(fileName,None) # None means that will be printed on default printer