Golang使用Windows底层开发那些事

通过上一篇博客知道,Python可以通过pywin32实现Windows底层开发,最常见的是word和Excel处理,自动打印等等。
我曾经说过,编程语言只是工具,只要工具玩的溜,一切皆有可能。按照上一篇博客实现的功能,使用Golang同样能实现。
Golang调用Windows底层接口,可以借助第三方库github.com/go-ole/go-ole
如果对Golang熟悉的话,不妨看看go-ole源码,从源码文件发现,它是通过标准库syscall调用Windows底层文件dll实现的,如图所示
在这里插入图片描述

在这里插入图片描述
大致了解第三库go-ole底层原理之后,下一步就讲述如下使用。

第三库go-ole

第三库go-ole虽然没有文档说明,但已提供示例代码讲述如何使用。分析示例代码得知,整个库无非就调用这么几个函数方法:
oleutil.CreateObject(“Excel.Application”):创建对象,固定写法,CreateObject的参数可变的。
unknown.QueryInterface(ole.IID_IDispatch):查询接口,固定写法。
oleutil.PutProperty():设置对象的属性。
oleutil.GetProperty():获取属性。
oleutil.MustGetProperty().ToIDispatch():获取属性,在GetProperty()基础上在封装一下。
oleutil.CallMethod():调用方法。
oleutil.MustCallMethod():调用方法,在CallMethod()基础上在封装一下。
Release():释放资源。
ole.CoInitialize(0):初始化。
ole.CoUninitialize():释放资源。
使用win32com调用com组件的时候,需要用ole.CoInitialize初始化一下,最后还需要用ole.CoUninitialize释放资源。
整个库主要使用上述的函数方法,有关各个函数参数就自行查看源码定义或示例代码的具体使用了。

将Word转pdf

示例代码没有延时Word如何使用,但可以通过微软官网文档找到具体的使用方法,示例代码如下:

package main

import (
	ole "github.com/go-ole/go-ole"
	"github.com/go-ole/go-ole/oleutil"
)

func setWord(fileName string)  {
	ole.CoInitialize(0)
	unknown, _ := oleutil.CreateObject("Word.Application")
	word, _ := unknown.QueryInterface(ole.IID_IDispatch)
	oleutil.PutProperty(word, "Visible", false)
	documents := oleutil.MustGetProperty(word, "Documents").ToIDispatch()
	document := oleutil.MustCallMethod(documents, "Open", fileName).ToIDispatch()
	oleutil.MustCallMethod(document, "SaveAs2", "E:\\mygo\\bb.pdf", 17).ToIDispatch()
	document.Release()
	documents.Release()
	word.Release()
	ole.CoUninitialize()
}

func main() {
	setWord("E:\\mygo\\abc.docx")
}

Excel设置页面和边框、转PDF

对于Excel的操作,示例代码没有太多说明,也是可以结合微软官网文档实现我们想要的功能,代码如下:

package main

import (
	ole "github.com/go-ole/go-ole"
	"github.com/go-ole/go-ole/oleutil"
)

func setExcel(fileName string){
	ole.CoInitialize(0)
	unknown, _ := oleutil.CreateObject("Excel.Application")
	excel, _ := unknown.QueryInterface(ole.IID_IDispatch)
	oleutil.PutProperty(excel, "Visible", false)
	workbooks := oleutil.MustGetProperty(excel, "Workbooks").ToIDispatch()
	workbook, _ := oleutil.CallMethod(workbooks, "Open", fileName)
	//defer workbook.ToIDispatch().Release()
	worksheet := oleutil.MustGetProperty(workbook.ToIDispatch(), "Worksheets", 1).ToIDispatch()
	//defer worksheet.Release()
	ps := oleutil.MustGetProperty(worksheet, "PageSetup").ToIDispatch()
	oleutil.PutProperty(ps, "LeftHeader", "")
	oleutil.PutProperty(ps, "CenterHeader", "")
	oleutil.PutProperty(ps, "RightHeader", "")
	oleutil.PutProperty(ps, "LeftFooter", "")
	oleutil.PutProperty(ps, "CenterFooter", "")
	oleutil.PutProperty(ps, "RightFooter", "")
	oleutil.PutProperty(ps, "LeftMargin", 0)
	oleutil.PutProperty(ps, "RightMargin", 0)
	oleutil.PutProperty(ps, "TopMargin", 0)
	oleutil.PutProperty(ps, "BottomMargin", 0)
	oleutil.PutProperty(ps, "HeaderMargin", 0)
	oleutil.PutProperty(ps, "FooterMargin", 0)
	oleutil.PutProperty(ps, "Orientation", 2)
	oleutil.PutProperty(ps, "Zoom", false)
	oleutil.PutProperty(ps, "FitToPagesWide", 1)
	oleutil.PutProperty(ps, "FitToPagesTall", false)
	oleutil.PutProperty(ps, "CenterVertically", true)
	oleutil.PutProperty(ps, "CenterHorizontally", true)
	oleutil.PutProperty(ps, "Draft", false)
	oleutil.PutProperty(ps, "FirstPageNumber", true)
	oleutil.MustCallMethod(worksheet, "ExportAsFixedFormat", 0, "E:\\mygo\\aa.pdf").ToIDispatch()
	ps.Release()
	worksheet.Release()
	workbooks.Release()
	excel.Release()
	ole.CoUninitialize()
}

func main() {
	setExcel("E:\\mygo\\abc.xls")
}

保存文件的时候,最好使用绝对路径,如果使用相对路径,最终保存的文件可能不在go文件所在的路径。

总结

不管是用Python还是Golang实现Windows底层开发,最终实现功能都要依赖微软官网文档提供的接口方法。
此外,Golang还可以实现打印机功能,例如网络打印功能