KMNConvertTool.swift 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. //
  2. // KMNConvertPDFManager.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by 丁林圭 on 2024/10/23.
  6. //
  7. import Cocoa
  8. class KMNConvertTool: NSObject {
  9. static let imageExtensions = ["jpg","cur","bmp","jpeg","gif","png","tiff","tif",/*@"pic",*/"ico","icns","tga","psd","eps","hdr","jp2","jpc","pict","sgi","heic"]
  10. static let pdfExtensions = ["pdf"]
  11. static let officeExtensions = ["doc", "docx", "xls", "xlsx", "ppt", "pptx"]
  12. class func supportImageFileType() -> [String] {
  13. return imageExtensions
  14. }
  15. class func supportPDFFileType() -> [String] {
  16. return pdfExtensions
  17. }
  18. @objc class func isImageType(_ exn: String) -> Bool {
  19. return KMNConvertTool.imageExtensions.contains(exn.lowercased())
  20. }
  21. @objc class func isPDFType(_ exn: String) -> Bool {
  22. return KMNConvertTool.pdfExtensions.contains(exn.lowercased())
  23. }
  24. @objc class func isOfficeType(_ exn: String) -> Bool {
  25. return KMNConvertTool.officeExtensions.contains(exn.lowercased())
  26. }
  27. class func convertOffice(filePath: String, completionBlock:@escaping (String?)->Void) -> Void {
  28. let today = Date()
  29. let dateFormatter = DateFormatter()
  30. dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
  31. let dateString = dateFormatter.string(from: today)
  32. let folderPath = "convertToPDF_office_" + dateString + "." + "pdf"
  33. let savePath: String? = folderPath.kUrlToPDFFolderPath() as String
  34. KMConvertPDFManager.convertFile(filePath, savePath: savePath!) { success, errorDic in
  35. if errorDic != nil || !success || !FileManager.default.fileExists(atPath: savePath!) {
  36. if FileManager.default.fileExists(atPath: savePath!) {
  37. try?FileManager.default.removeItem(atPath: savePath!)
  38. }
  39. let alert = NSAlert.init()
  40. alert.alertStyle = .critical
  41. var infoString = ""
  42. if errorDic != nil {
  43. for key in (errorDic! as Dictionary).keys {
  44. infoString = infoString.appendingFormat("%@\n", errorDic![key] as! CVarArg)
  45. }
  46. }
  47. alert.informativeText = NSLocalizedString("Please install Microsoft Office to create PDFs from Office files", comment: "")
  48. alert.messageText = NSLocalizedString("Failed to Create PDF", comment: "")
  49. alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
  50. alert.runModal()
  51. completionBlock(nil)
  52. return
  53. }
  54. if !savePath!.isPDFValid() {
  55. let alert = NSAlert()
  56. alert.alertStyle = .critical
  57. alert.messageText = NSLocalizedString("An error occurred while opening this document. The file is damaged and could not be repaired.", comment: "")
  58. alert.runModal()
  59. completionBlock(nil)
  60. return
  61. }
  62. completionBlock(savePath)
  63. }
  64. }
  65. class func openDocumentWithImageFromPasteboard(_ pboard: NSPasteboard, error outError: AutoreleasingUnsafeMutablePointer<NSError?>?) -> CPDFDocument? {
  66. var document: CPDFDocument? = nil
  67. var data: Data? = nil
  68. if pboard.canReadItem(withDataConformingToTypes: [NSPasteboard.PasteboardType.pdf.rawValue]) {
  69. data = pboard.data(forType: NSPasteboard.PasteboardType.pdf)
  70. } else if pboard.canReadItem(withDataConformingToTypes: [NSPasteboard.PasteboardType.postScript.rawValue]) {
  71. data = pboard.data(forType: NSPasteboard.PasteboardType.postScript)
  72. } else if pboard.canReadItem(withDataConformingToTypes: [NSPasteboard.PasteboardType.tiff.rawValue]) {
  73. data = KMNConvertTool.convertTIFFDataToPDF(pboard.data(forType: NSPasteboard.PasteboardType.tiff) ?? Data())
  74. } else {
  75. let images = pboard.readObjects(forClasses: [NSImage.self], options: [:])
  76. let strings = pboard.readObjects(forClasses: [NSAttributedString.self], options: [:])
  77. if images?.count ?? 0 > 0 {
  78. data = KMNConvertTool.convertTIFFDataToPDF((images![0] as AnyObject).tiffRepresentation!)
  79. } else if strings?.count ?? 0 > 0 {
  80. data = KMOCTool.convertStringsToPDF(withString: strings ?? [""]) // convertStringsToPDF(strings!)
  81. }
  82. }
  83. if let data = data {
  84. document = CPDFDocument(data: data)
  85. } else if let outError = outError {
  86. outError.pointee = NSError(domain: "SKDocumentErrorDomain", code: 3, userInfo: [NSLocalizedDescriptionKey: NSLocalizedString("Unable to load data from clipboard", comment: "Error description")])
  87. }
  88. return document
  89. }
  90. class func convertTIFFDataToPDF(_ tiffData: Data) -> Data? {
  91. guard let imsrc = CGImageSourceCreateWithData(tiffData as CFData, [kCGImageSourceTypeIdentifierHint: kUTTypeTIFF] as CFDictionary), CGImageSourceGetCount(imsrc) > 0, let cgImage = CGImageSourceCreateImageAtIndex(imsrc, 0, nil) else { return nil }
  92. let pdfData = NSMutableData(capacity: tiffData.count)
  93. let consumer = CGDataConsumer(data: pdfData! as CFMutableData)!
  94. var rect = CGRect(x: 0, y: 0, width: CGFloat(cgImage.width), height: CGFloat(cgImage.height))
  95. let ctxt = CGContext(consumer: consumer, mediaBox: &rect, nil)
  96. ctxt!.beginPDFPage(nil)
  97. ctxt!.draw(cgImage, in: rect)
  98. ctxt!.endPDFPage()
  99. ctxt!.closePDF()
  100. return pdfData as? Data
  101. }
  102. }