excel.go 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. package cmd
  2. import (
  3. "fmt"
  4. "log"
  5. "github.com/go-ole/go-ole"
  6. "github.com/go-ole/go-ole/oleutil"
  7. )
  8. // @title ExcelSheetExportAsPdf
  9. // @description 把excel文件指定的sheet导出为pdf文件
  10. // @param xlsxPath string excel文件路径,pdfPath string pdf文件路径
  11. // @return
  12. func ExcelSheetExportAsPdf(xlsxPath, pdfPath string, sheetIndex int) error {
  13. //CoInitialize是Windows提供的API函数,用来告诉 Windows以单线程的方式创建com对象。
  14. //应用程序调用com库函数(除CoGetMalloc和内存分配函数)之前必须初始化com库。
  15. ole.CoInitialize(0)
  16. defer ole.CoUninitialize()
  17. //创建com对象
  18. iunk, err := oleutil.CreateObject("Excel.Application")
  19. if err != nil {
  20. log.Printf("error creating Wps object: %s", err)
  21. return fmt.Errorf("error creating Wps object: %s", err)
  22. }
  23. defer iunk.Release()
  24. // 获取能够遍历的对象
  25. excel := iunk.MustQueryInterface(ole.IID_IDispatch)
  26. defer excel.Release()
  27. //获取工作簿对象
  28. workbooks := oleutil.MustGetProperty(excel, "Workbooks").ToIDispatch()
  29. defer workbooks.Release()
  30. //打开指定工作簿
  31. workbook := oleutil.MustCallMethod(workbooks, "Open", xlsxPath).ToIDispatch()
  32. defer workbook.Release()
  33. //获取指定sheet
  34. worksheet := oleutil.MustGetProperty(workbook, "Worksheets", sheetIndex).ToIDispatch()
  35. defer worksheet.Release()
  36. //获取指定sheet的PageSetup
  37. PageSetup, err := oleutil.GetProperty(worksheet, "PageSetup")
  38. if err != nil {
  39. log.Printf("Worksheets(1) get PageSetup error: %s", err)
  40. } else {
  41. ////设置指定sheet的PageSetup.FitToPagesTall
  42. _, err = oleutil.PutProperty(PageSetup.ToIDispatch(), "FitToPagesWide", 1)
  43. if err != nil {
  44. log.Printf("Worksheets(1).PageSetup put FitToPagesTall error: %s", err)
  45. }
  46. _, err = oleutil.PutProperty(PageSetup.ToIDispatch(), "LeftMargin", 0)
  47. if err != nil {
  48. log.Printf("Worksheets(1).PageSetup put LeftMargin error: %s", err)
  49. }
  50. _, err = oleutil.PutProperty(PageSetup.ToIDispatch(), "RightMargin", 0)
  51. if err != nil {
  52. log.Printf("Worksheets(1).PageSetup put RightMargin error: %s", err)
  53. }
  54. _, err = oleutil.PutProperty(PageSetup.ToIDispatch(), "TopMargin", 0)
  55. if err != nil {
  56. log.Printf("Worksheets(1).PageSetup put TopMargin error: %s", err)
  57. }
  58. _, err = oleutil.PutProperty(PageSetup.ToIDispatch(), "BottomMargin", 0)
  59. if err != nil {
  60. log.Printf("Worksheets(1).PageSetup put BottomMargin error: %s", err)
  61. }
  62. }
  63. // 导出为指定格式
  64. oleutil.MustCallMethod(worksheet, "ExportAsFixedFormat", 0, pdfPath)
  65. //todo 如果不保存wps会弹窗,必须先保存.暂时未找到解决方案
  66. oleutil.PutProperty(workbook, "Saved", true)
  67. oleutil.MustCallMethod(workbook, "Close")
  68. oleutil.MustCallMethod(excel, "Quit")
  69. return nil
  70. }
  71. // @title ExcelExportAsPdf
  72. // @description excel文件导出为pdf文件
  73. // @param xlsxPath string excel文件路径,pdfPath string pdf文件路径
  74. // @return
  75. func ExcelExportAsPdf(xlsxPath, pdfPath string) error {
  76. //CoInitialize是Windows提供的API函数,用来告诉 Windows以单线程的方式创建com对象。
  77. //应用程序调用com库函数(除CoGetMalloc和内存分配函数)之前必须初始化com库。
  78. ole.CoInitialize(0)
  79. defer ole.CoUninitialize()
  80. //创建com对象
  81. iunk, err := oleutil.CreateObject("Excel.Application")
  82. if err != nil {
  83. log.Printf("error creating Wps object: %s", err)
  84. return fmt.Errorf("error creating Wps object: %s", err)
  85. }
  86. defer iunk.Release()
  87. // 获取能够遍历的对象
  88. excel := iunk.MustQueryInterface(ole.IID_IDispatch)
  89. defer excel.Release()
  90. //获取工作簿对象
  91. workbooks := oleutil.MustGetProperty(excel, "Workbooks").ToIDispatch()
  92. defer workbooks.Release()
  93. //打开指定工作簿
  94. workbook := oleutil.MustCallMethod(workbooks, "Open", xlsxPath).ToIDispatch()
  95. defer workbook.Release()
  96. //获取指定sheet
  97. worksheet := oleutil.MustGetProperty(workbook, "Worksheets", 1).ToIDispatch()
  98. defer worksheet.Release()
  99. //获取指定sheet的PageSetup
  100. PageSetup, err := oleutil.GetProperty(worksheet, "PageSetup")
  101. if err != nil {
  102. log.Printf("Worksheets(1) get PageSetup error: %s", err)
  103. } else {
  104. ////设置指定sheet的PageSetup.FitToPagesTall
  105. _, err = oleutil.PutProperty(PageSetup.ToIDispatch(), "FitToPagesWide", 1)
  106. if err != nil {
  107. log.Printf("Worksheets(1).PageSetup put FitToPagesTall error: %s", err)
  108. }
  109. _, err = oleutil.PutProperty(PageSetup.ToIDispatch(), "LeftMargin", 0)
  110. if err != nil {
  111. log.Printf("Worksheets(1).PageSetup put LeftMargin error: %s", err)
  112. }
  113. _, err = oleutil.PutProperty(PageSetup.ToIDispatch(), "RightMargin", 0)
  114. if err != nil {
  115. log.Printf("Worksheets(1).PageSetup put RightMargin error: %s", err)
  116. }
  117. _, err = oleutil.PutProperty(PageSetup.ToIDispatch(), "TopMargin", 0)
  118. if err != nil {
  119. log.Printf("Worksheets(1).PageSetup put TopMargin error: %s", err)
  120. }
  121. _, err = oleutil.PutProperty(PageSetup.ToIDispatch(), "BottomMargin", 0)
  122. if err != nil {
  123. log.Printf("Worksheets(1).PageSetup put BottomMargin error: %s", err)
  124. }
  125. }
  126. // 导出为指定格式
  127. oleutil.MustCallMethod(worksheet, "ExportAsFixedFormat", 0, pdfPath)
  128. //todo 如果不保存wps会弹窗,必须先保存.暂时未找到解决方案
  129. oleutil.PutProperty(workbook, "Saved", true)
  130. oleutil.MustCallMethod(workbook, "Close")
  131. oleutil.MustCallMethod(excel, "Quit")
  132. return nil
  133. }
  134. // @title ExcelPrintOut
  135. // @description 调用系统的pdf虚拟打印机生成pdf文件.
  136. // @param xlsxPath string excel文档路径,pdfPath string 生成的pdf文档路径
  137. // @return
  138. // todo 由于打印完需要手动点击确认保存,未找到解决方法
  139. func ExcelPrintOut(xlsxPath, pdfPath string) error {
  140. defer func() {
  141. if err := recover(); err != nil {
  142. log.Printf("ExcelPrintOut error: %v\n", err)
  143. }
  144. }()
  145. ole.CoInitialize(0)
  146. defer ole.CoUninitialize()
  147. unknown, err := oleutil.CreateObject("KET.Application")
  148. if err != nil {
  149. log.Printf("creating Excel object error: %s", err)
  150. return fmt.Errorf("please make sure wps installed.\ncreating Excel object error: %s\n", err)
  151. }
  152. defer unknown.Release()
  153. excel := unknown.MustQueryInterface(ole.IID_IDispatch)
  154. defer excel.Release()
  155. oleutil.PutProperty(excel, "DisplayAlerts", false)
  156. oleutil.PutProperty(excel, "Visible", false)
  157. // opening then saving works due to the call to doc.Settings.SetUpdateFieldsOnOpen(true) above
  158. workbooks := oleutil.MustGetProperty(excel, "Workbooks").ToIDispatch()
  159. defer workbooks.Release()
  160. workbook := oleutil.MustCallMethod(workbooks, "Open", xlsxPath).ToIDispatch()
  161. defer workbook.Release()
  162. //oleutil.MustPutProperty(books, "ActiveWorkBook",1)
  163. // println("==============1")
  164. worksheet := oleutil.MustGetProperty(workbook, "Worksheets", 1).ToIDispatch()
  165. defer worksheet.Release()
  166. // println("==============2")
  167. // 如果 FitToPagesTall 此屬性為 False,Microsoft Excel 會根據 FitToPagesWide 屬性調整工作表。
  168. ret, err := oleutil.GetProperty(worksheet, "", "PageSetup", "FitToPagesTall", 1)
  169. fmt.Printf("FitToPagesTall %v,err==============>%v\n", ret, err)
  170. _, err = oleutil.PutProperty(worksheet, "", "PageSetup", ".FitToPagesWide", 1)
  171. fmt.Printf("FitToPagesWide err==============>%v\n", err)
  172. //
  173. // https://docs.microsoft.com/zh-cn/office/vba/api/excel.sheets.printout
  174. /*
  175. PrintOut(From, To, Copies, Preview, ActivePrinter, PrintToFile, Collate, PrToFileName)
  176. From 打印的開始頁號。如果省略此參數,則從起始位置開始打印。
  177. To 打印的終止頁號。如果省略此參數,則打印至最後一頁。
  178. Copies 打印份數。如果省略此參數,則只打印一份。
  179. Preview 如果爲 True,Microsoft Excel 將在打印對象之前調用打印預覽。如果爲 False(或省略該參數),則立即打印對象。
  180. ActivePrinter 設置活動打印機的名稱。
  181. PrintToFile 如果爲 True,則打印到文件。如果沒有指定 PrToFileName,Microsoft Excel 將提示用戶輸入要使用的輸出文件的文件名。
  182. Collate 如果爲 True,則逐份打印多個副本。
  183. PrToFileName 如果 PrintToFile 設爲 True,則該參數指定要打印到的文件名。
  184. 注:From 和 To 所描述的“頁”指的是要打印的頁,並非指定工作表或工作簿中的全部頁。
  185. */
  186. oleutil.MustCallMethod(worksheet, "PrintOut", 1, 1, 1, false, "导出为WPS PDF", true, pdfPath, true)
  187. oleutil.MustCallMethod(workbook, "Close")
  188. oleutil.MustCallMethod(excel, "Quit")
  189. return nil
  190. }