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

时间:2015-01-20 16:53:33

标签: python .net excel printing python.net

我一直在寻找很多方法打印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)

我已经从here下载并安装了Interop程序集,因此应该安装它们。

我找到了一种使用IronPython和Interop dll在here中打印excel文件的方法。

我的主要问题是我需要打印一些excel文件而不打开Excel应用程序,如果您有其他选择是受欢迎的

如果没有其他选择,我该怎么做才能找到装配?


其他信息:要在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);
}

1 个答案:

答案 0 :(得分:1)

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

接下来的方法是:

  1. 使用.net编写代码,并使用尽可能简单的界面公开此代码 避免暴露COM类型!
    避免管理州!
  2. 从python中使用库。
  3. 第1步

    • 创建名为 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从输出中放入 任何位置可从路径(您可以使用.pth file)。
    • 导入库并像这样使用它:

      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