|
1 | 1 | import Carbon.HIToolbox
|
| 2 | +import PDFKit |
2 | 3 | import WebKit
|
3 | 4 |
|
4 | 5 | #if os(iOS)
|
@@ -83,30 +84,90 @@ class MPreviewView: WKWebView, WKUIDelegate, WKNavigationDelegate {
|
83 | 84 |
|
84 | 85 | public func exportPdf() {
|
85 | 86 | guard let vc = ViewController.shared() else { return }
|
| 87 | + // 获取 WKWebView 的内容大小 |
| 88 | + var a4Size = CGSize(width: 800, height: 1120) |
| 89 | + if UserDefaultsManagement.isOnExportPPT { |
| 90 | + a4Size = CGSize(width: 1536, height: 957) |
| 91 | + } |
86 | 92 |
|
87 |
| - if #available(macOS 11.0.0, *) { |
88 |
| - DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { |
89 |
| - let config = WKPDFConfiguration() |
90 |
| - // Render the PDF |
91 |
| - super.createPDF(configuration: config) { result in |
92 |
| - switch result { |
93 |
| - case .success(let data): |
94 |
| - if let path = NSSearchPathForDirectoriesInDomains(.downloadsDirectory, .userDomainMask, true).first { |
95 |
| - let currentName = self.note?.getTitle() |
96 |
| - let filePath: String = path + "/" + (currentName ?? "MiaoYan") + ".pdf" |
97 |
| - try! data.write(to: URL(fileURLWithPath: filePath)) |
98 |
| - vc.toastExport(status: true) |
99 |
| - } |
| 93 | + let pageWidth = a4Size.width |
| 94 | + let pageHeight = a4Size.height |
| 95 | + let maxHeight: CGFloat = 14355.0 |
| 96 | + |
| 97 | + super.frame.size.width = pageWidth |
| 98 | + |
| 99 | + super.evaluateJavaScript("document.body.scrollHeight", completionHandler: { height, error in |
| 100 | + guard let height = height as? CGFloat, error == nil else { |
| 101 | + vc.toastExport(status: false) |
| 102 | + return |
| 103 | + } |
| 104 | + if #available(macOS 11.0, *) { |
| 105 | + let numberOfParts = Int(ceil(height / maxHeight)) |
| 106 | + let newDocument = PDFDocument() |
| 107 | + |
| 108 | + // 设置 PDF 分页 |
| 109 | + func processPart(_ partIndex: Int) { |
| 110 | + let partY = CGFloat(partIndex) * maxHeight |
| 111 | + let partHeight = min(maxHeight, height - partY) |
| 112 | + |
| 113 | + let pdfConfiguration = WKPDFConfiguration() |
| 114 | + pdfConfiguration.rect = CGRect(x: 0, y: partY, width: super.bounds.width, height: partHeight) |
| 115 | + |
| 116 | + super.createPDF(configuration: pdfConfiguration) { result in |
| 117 | + switch result { |
| 118 | + case .success(let pdfData): |
| 119 | + // 使用 PDFKit 进行分页 |
| 120 | + |
| 121 | + let pdfDocument = PDFDocument(data: pdfData) |
| 122 | + |
| 123 | + for i in 0 ..< (pdfDocument?.pageCount ?? 0) { |
| 124 | + guard let page = pdfDocument?.page(at: i) else { |
| 125 | + return |
| 126 | + } |
| 127 | + |
| 128 | + let pageBounds = page.bounds(for: .cropBox) |
| 129 | + let subPageCount = Int(ceil(pageBounds.height / a4Size.height)) |
| 130 | + |
| 131 | + for j in 0 ..< subPageCount { |
| 132 | + let subPageRect = CGRect(x: 0, y: CGFloat(subPageCount - j - 1) * a4Size.height, width: pageWidth, height: a4Size.height) |
100 | 133 |
|
101 |
| - case .failure(let error): |
102 |
| - print(error) |
103 |
| - vc.toastExport(status: false) |
| 134 | + guard let subPage = page.copy() as? PDFPage else { |
| 135 | + return |
| 136 | + } |
| 137 | + |
| 138 | + subPage.setBounds(subPageRect, for: .cropBox) |
| 139 | + newDocument.insert(subPage, at: newDocument.pageCount) |
| 140 | + } |
| 141 | + } |
| 142 | + |
| 143 | + if partIndex < numberOfParts - 1 { |
| 144 | + processPart(partIndex + 1) |
| 145 | + } else { |
| 146 | + if let newPDFData = newDocument.dataRepresentation() { |
| 147 | + if let path = NSSearchPathForDirectoriesInDomains(.downloadsDirectory, .userDomainMask, true).first { |
| 148 | + vc.toastExport(status: true) |
| 149 | + let currentName = self.note?.getTitle() |
| 150 | + let filePath: String = path + "/" + (currentName ?? "MiaoYan") + ".pdf" |
| 151 | + try! newPDFData.write(to: URL(fileURLWithPath: filePath)) |
| 152 | + } |
| 153 | + |
| 154 | + } else {} |
| 155 | + } |
| 156 | + |
| 157 | + case .failure: |
| 158 | + vc.toastExport(status: false) |
| 159 | + return |
| 160 | + } |
104 | 161 | }
|
105 | 162 | }
|
| 163 | + |
| 164 | + processPart(0) |
| 165 | + |
| 166 | + } else { |
| 167 | + // Fallback on earlier versions |
| 168 | + vc.toastExport(status: false) |
106 | 169 | }
|
107 |
| - } else { |
108 |
| - vc.toastExport(status: false) |
109 |
| - } |
| 170 | + }) |
110 | 171 | }
|
111 | 172 |
|
112 | 173 | public func slideTo(index: Int) {
|
|
0 commit comments