0

I open url using uiwebview then I show share sheet, but there is no create pdf button. I want show the create pdf button like safari, and create pdf from url then share the pdf. how to do it?

OR how to create pdf from url webview/uiview then save pdf to files?

this is my share sheet this is my share sheet

and this is safari share sheet have create pdf button safari share sheet

and this my code to show share sheet

let items = [URL(string: "https://www.apple.com")!]
    let ac = UIActivityViewController(activityItems: items, applicationActivities: nil)
    present(ac, animated: true)
Eggy
  • 522
  • 5
  • 29
  • 1
    see here : https://stackoverflow.com/questions/15813005/creating-pdf-file-from-uiwebview –  May 13 '21 at 05:17

2 Answers2

1
extension WKWebView {
    // Call this function when WKWebView finish loading
    func exportAsPdfFromWebView() -> String {
        let pdfData = createPdfFile(printFormatter: self.viewPrintFormatter())
        return self.saveWebViewPdf(data: pdfData)
    }

    func createPdfFile(printFormatter: UIViewPrintFormatter) -> NSMutableData {
        let originalBounds = self.bounds
        self.bounds = CGRect(x: originalBounds.origin.x,
                             y: bounds.origin.y,
                             width: self.bounds.size.width,
                             height: self.scrollView.contentSize.height)
        let pdfPageFrame = CGRect(x: 0, y: 0, width: self.bounds.size.width,
                                  height: self.scrollView.contentSize.height)
        let printPageRenderer = UIPrintPageRenderer()
        printPageRenderer.addPrintFormatter(printFormatter, startingAtPageAt: 0)
        printPageRenderer.setValue(NSValue(cgRect: UIScreen.main.bounds), forKey: "paperRect")
        printPageRenderer.setValue(NSValue(cgRect: pdfPageFrame), forKey: "printableRect")
        self.bounds = originalBounds
        return printPageRenderer.generatePdfData()
    }

    // Save pdf file in document directory
    func saveWebViewPdf(data: NSMutableData) -> String {

        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        let docDirectoryPath = paths[0]
        let pdfPath = docDirectoryPath.appendingPathComponent("webViewPdf.pdf")
        if data.write(to: pdfPath, atomically: true) {
            return pdfPath.path
        } else {
            return ""
        }
    }
}
extension UIPrintPageRenderer {

    func generatePdfData() -> NSMutableData {
        let pdfData = NSMutableData()
        UIGraphicsBeginPDFContextToData(pdfData, self.paperRect, nil)
        self.prepare(forDrawingPages: NSMakeRange(0, self.numberOfPages))
        let printRect = UIGraphicsGetPDFContextBounds()
        for pdfPage in 0..<self.numberOfPages {
            UIGraphicsBeginPDFPage()
            self.drawPage(at: pdfPage, in: printRect)
        }
        UIGraphicsEndPDFContext();
        return pdfData
    }
}

You can create pdf from url webview/uiview then save pdf to files using this

iOS Developer
  • 464
  • 6
  • 24
0

I found the answer from other

first I create new class PDF.swift

    class func generate(using printFormatter: UIPrintFormatter) -> String {

        // assign the print formatter to the print page renderer
        let renderer = UIPrintPageRenderer()
        renderer.addPrintFormatter(printFormatter, startingAtPageAt: 0)
        
//        static let ANSI_A        = CGSize(width:612,height:792)
//        static let ANSI_B        = CGSize(width:792,height:1224)
//        static let ANSI_C        = CGSize(width:1584,height:1224)
//        static let ANSI_D        = CGSize(width:2448,height:1584)
//        static let ANSI_E        = CGSize(width:3168,height:2448)
//
//        static let ISO216_A0     = CGSize(width:2384,height:3370)
//        static let ISO216_A1     = CGSize(width:1684,height:2384)
//        static let ISO216_A2     = CGSize(width:1190,height:1684)
//        static let ISO216_A3     = CGSize(width:842,height:1190)
//        static let ISO216_A4     = CGSize(width:595,height:842)
//        static let ISO216_A5     = CGSize(width:420,height:595)
//        static let ISO216_A6     = CGSize(width:298,height:420)
//        static let ISO216_A7     = CGSize(width:210,height:298)
//        static let ISO216_A8     = CGSize(width:148,height:210)

        // assign paperRect and printableRect values
        let page = CGRect(x: 0, y: 0, width: 1190, height: 842) // A3 landscape
//        let page = CGRect(x: 0, y: 0, width: 2384, height: 800) // A4, 72 dpi
        renderer.setValue(page, forKey: "paperRect")
        renderer.setValue(page, forKey: "printableRect")
        

        // create pdf context and draw each page
        let pdfData = NSMutableData()
//        UIGraphicsBeginPDFContextToData(pdfData, .zero, nil)
        UIGraphicsBeginPDFContextToData(pdfData, page, nil)

        for i in 0..<renderer.numberOfPages {
            UIGraphicsBeginPDFPage()
            renderer.drawPage(at: i, in: UIGraphicsGetPDFContextBounds())
        }

        UIGraphicsEndPDFContext();

        // save data to a pdf file and return
        guard nil != (try? pdfData.write(to: outputURL, options: .atomic))
            else { fatalError("Error writing PDF data to file.") }

        return outputURL.absoluteString
    }

    private class var outputURL: URL {

        guard let directory = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
            else { fatalError("Error getting user's document directory.") }

        let url = directory.appendingPathComponent(outputFileName).appendingPathExtension("pdf")
        print("open \(url.path)")
        
        
        
        return url
    }

    private class var outputFileName: String {
        return "generated-\(Int(Date().timeIntervalSince1970))"
    }

and call the function to generate pdf then share using share sheet to save files

let uiPDFData = PDF.generate(using: self.uiWebViewPrintFormatter()) print(uiPDFData)

DispatchQueue.main.async{
    let fileURL = NSURL(fileURLWithPath: (uiPDFData))

    // Create the Array which includes the files you want to share
    var filesToShare = [Any]()

    // Add the path of the file to the Array
    filesToShare.append(fileURL)

    // Make the activityViewContoller which shows the share-view
    let activityViewController = UIActivityViewController(activityItems: filesToShare, applicationActivities: nil)

    // Show the share-view
    if UIDevice.current.userInterfaceIdiom == .pad {
        if let popup = activityViewController.popoverPresentationController {
            popup.sourceView = self.view
            popup.sourceRect = CGRect(x: self.view.frame.size.width / 2, y: self.view.frame.size.height / 4, width: 0, height: 0)
        }
    }

    self.present(activityViewController, animated: true, completion: nil)
}
Eggy
  • 522
  • 5
  • 29