KMURLToPDF.swift 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. //
  2. // KMURLToPDF.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by Niehaoyu on 2024/10/16.
  6. //
  7. import Cocoa
  8. import WebKit
  9. import PDFKit
  10. class KMURLToPDF: NSObject, WKNavigationDelegate {
  11. @objc public static let shareInstance = KMURLToPDF()
  12. var webView: WKWebView!
  13. var completion: ((URL?, Error?) -> Void)?
  14. var savePath: String = ""
  15. var saveName: String = ""
  16. func convertHtmlFileToPDF(fromPath: String, toPath: String, completion: @escaping (URL?, Error?) -> Void) {
  17. self.completion = completion
  18. savePath = toPath
  19. webView = WKWebView(frame: CGRectMake(0, 0, 1920, 1080))
  20. webView.navigationDelegate = self
  21. let fileURL: URL = URL(fileURLWithPath: fromPath)
  22. let readAccessURL = fileURL.deletingLastPathComponent()
  23. webView.loadFileURL(fileURL, allowingReadAccessTo: readAccessURL)
  24. saveName = fromPath.deletingPathExtension.lastPathComponent + ".pdf"
  25. }
  26. func convertLinkString(string: String, toPath: String, completion: @escaping (URL?, Error?) -> Void) {
  27. self.completion = completion
  28. savePath = toPath
  29. webView = WKWebView(frame: CGRectMake(0, 0, 1920, 1080))
  30. webView.navigationDelegate = self
  31. if let url = URL(string: string) {
  32. webView.load(URLRequest(url: url))
  33. }
  34. }
  35. func stopLoading() {
  36. webView?.stopLoading()
  37. }
  38. //MARK: - WKNavigationDelegate
  39. func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
  40. webView.stopLoading()
  41. let configuration: WKPDFConfiguration = WKPDFConfiguration()
  42. var contentWidth: CGFloat = 0
  43. var contentHeight: CGFloat = 0
  44. webView.evaluateJavaScript("document.title") { (result, error) in
  45. if let name = result as? String {
  46. self.saveName = name + ".pdf"
  47. }
  48. webView.evaluateJavaScript("document.body.scrollWidth") { (width, error) in
  49. if let width = width as? CGFloat {
  50. contentWidth = width
  51. }
  52. // 获取内容高度
  53. webView.evaluateJavaScript("document.body.scrollHeight") { (height, error) in
  54. if let height = height as? CGFloat {
  55. contentHeight = height
  56. }
  57. if contentWidth > 0 && contentHeight > 0 {
  58. configuration.rect = CGRectMake(0, 0, contentWidth, contentHeight)
  59. webView.createPDF(configuration: configuration) { result in
  60. switch result {
  61. case .success(let pdfData):
  62. // PDF successfully created, handle the PDF data
  63. let filePath = URL(fileURLWithPath: self.savePath.stringByAppendingPathComponent(self.saveName))
  64. if FileManager.default.fileExists(atPath: filePath.path) {
  65. try?FileManager.default.removeItem(atPath: filePath.path)
  66. }
  67. do {
  68. try pdfData.write(to: filePath)
  69. print("PDF saved to: \(filePath)")
  70. } catch {
  71. print("Failed to save PDF: \(error)")
  72. }
  73. guard let callBack = self.completion else {
  74. return
  75. }
  76. callBack(filePath, nil)
  77. case .failure(let error):
  78. guard let callBack = self.completion else {
  79. return
  80. }
  81. callBack(nil, error)
  82. }
  83. }
  84. } else {
  85. guard let callBack = self.completion else {
  86. return
  87. }
  88. callBack(nil, NSError(domain: "create error", code: 0))
  89. }
  90. }
  91. }
  92. }
  93. }
  94. func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
  95. webView.stopLoading()
  96. guard let callBack = self.completion else {
  97. return
  98. }
  99. callBack(nil, error)
  100. }
  101. func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
  102. webView.stopLoading()
  103. guard let callBack = self.completion else {
  104. return
  105. }
  106. callBack(nil, error)
  107. }
  108. }