【问题标题】:How to create, write and save a pdf file in a specific format in swift如何在 swift 中以特定格式创建、编写和保存 pdf 文件
【发布时间】:2021-09-29 19:15:11
【问题描述】:

我需要在pdf中写一个5列的数据数组(图片是为了解释格式),我需要左上角的标题,右上角的图像徽标,换行符,然后是行和图中显示的列。我为此做的代码如下。但是需要进行一些更改才能获得所需的确切格式,请分享一些更好的解决方案,此解决方案是否有更改

//Create File

func createPDF() {
        
        let text = gettudentDetails()
        
        let html = "<p>\(text)</p> <hr>"
        let fmt = UIMarkupTextPrintFormatter(markupText: html)

        // 2. Assign print formatter to UIPrintPageRenderer

        let render = UIPrintPageRenderer()
        render.addPrintFormatter(fmt, startingAtPageAt: 0)

        // 3. Assign paperRect and printableRect

        let page = CGRect(x: 0, y: 0, width: 595.2, height: 841.8) // A4, 72 dpi
        let printable = page.insetBy(dx: 0, dy: 0)

        render.setValue(NSValue(cgRect: page), forKey: "paperRect")
        render.setValue(NSValue(cgRect: printable), forKey: "printableRect")

        // 4. Create PDF context and draw

        let pdfData = NSMutableData()
        UIGraphicsBeginPDFContextToData(pdfData, .zero, nil)

        for i in 1...render.numberOfPages {
            UIGraphicsBeginPDFPage();
            let bounds = UIGraphicsGetPDFContextBounds()
            render.drawPage(at: i - 1, in: bounds)
        }

        UIGraphicsEndPDFContext();

        // 5. Save PDF file

        let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]

        guard let outputURL = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false).appendingPathComponent("studentRecord").appendingPathExtension("pdf")
        else { fatalError("Destination URL not created") }
        
        pdfData.write(toFile: "\(documentsPath)/studentRecord.pdf", atomically: true)
        loadPDF(filename: "studentRecord.pdf")
    }

//Get formated text
    func gettudentDetails() -> String {
        let image = #imageLiteral(resourceName: "splash_logo")
        let imgData = image.jpegData(compressionQuality: 0.5)

        var text = "<h1>Title Here </h1> <p><img src=\"\(imgData)\" alt=\"\" width=\"60\" height=\"72\" /></p> <hr> <br> </br> Nam &emsp; Father Name &emsp; Id &emsp; Age &emsp; DOB <hr> "
        for record in pdfRecordsList {
            
            let  name = (record.obj?.firstName ?? "")
            let FatherName = record.obj.fatherName ?? ""
            let id = record.obj?.id ?? 0
            let age = record.obj?.age ?? ""
            let dob = record.obj?.dob ?? ""

            text =  text + "<p>" + name + "&emsp;" + FatherName + "&emsp;" + "\(id)" + "&emsp;" + age + "&emsp;" + dob + "</p>"
        }
        
        return text
    }

//Load Pdf
  func loadPDF(filename: String) {
        let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
        let url = URL(fileURLWithPath: documentsPath, isDirectory: true).appendingPathComponent(filename)
        let urlRequest = URLRequest(url: url)
        webView.load(urlRequest)
    }

【问题讨论】:

    标签: ios swift pdf-generation


    【解决方案1】:

    经过大量搜索,阅读了几篇文章我找到了解决方案,代码在这里,只需将代码复制并粘贴到您的控制器,使用资产中添加的图像更改图像名称,然后运行

    import UIKit
    import WebKit
    
    class ViewController: UIViewController, WKNavigationDelegate {
        
        //MARK: - IBOUTLETS
        let imageLogo = UIImage(named: "logo")
        
        @IBOutlet weak var webView: WKWebView!
        //MARK: - Var& Objects
        
        var nameArr = ["Name1", "Name2", "Name 3", "Name4"]
        var fNameArr = ["FName1", "FName2", "FName3", "FName4"]
        var idArr = ["id 1", "Id 2", "Id 3", "Id 4"]
        var dobArr = ["9/12/1983", "7/23/1976", "7/5/1888", "6/7/1976"]
    
        override func viewDidLoad() {
            super.viewDidLoad()
            webView.navigationDelegate = self
            createPDF()
            
        }
        // Create and Save Pdf
        func createPDF() {
            
            let text = getDetails()
            
            let html = "\(text)"
            let fmt = UIMarkupTextPrintFormatter(markupText: html)
            
            // 2. Assign print formatter to UIPrintPageRenderer
            
            let render = UIPrintPageRenderer()
            render.addPrintFormatter(fmt, startingAtPageAt: 0)
            
            // 3. Assign paperRect and printableRect
            
            let page = CGRect(x: 0, y: 0, width: 595.2, height: 841.8) // A4, 72 dpi
            let printable = page.insetBy(dx: 20, dy: 80)
            
            render.setValue(NSValue(cgRect: page), forKey: "paperRect")
            render.setValue(NSValue(cgRect: printable), forKey: "printableRect")
            
            // 4. Create PDF context and draw
            
            let pdfData = NSMutableData()
            UIGraphicsBeginPDFContextToData(pdfData, .zero, nil)
            
            for i in 1...render.numberOfPages {
                UIGraphicsBeginPDFPage();
                let bounds = UIGraphicsGetPDFContextBounds()
                render.drawPage(at: i - 1, in: bounds)
            }
            
            UIGraphicsEndPDFContext();
            
            // 5. Save PDF file
            
            let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
            
            guard let outputURL = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false).appendingPathComponent("PDFReport").appendingPathExtension("pdf")
            else { fatalError("Destination URL not created") }
            
            pdfData.write(toFile: "\(documentsPath)/PDFReport.pdf", atomically: true)
            drawImageOnPDF(path: "\(documentsPath)/PDFReport.pdf")
            loadPDF(filename: "PDFReport.pdf")
        }
        //Open Pdf on web view
        func loadPDF(filename: String) {
            let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
            let url = URL(fileURLWithPath: documentsPath, isDirectory: true).appendingPathComponent(filename)
            let urlRequest = URLRequest(url: url)
            webView.load(urlRequest)
        }
        //get recorded deails in html string
        func getDetails() -> String {
            
            var text = """
    <h1>This is Pdf Report</h1>
       
    <br>
    
    <table style="width:  100%; border-collapse: collapse;">
        <thead style="border-top: 1px solid black; border-bottom: 1px solid black;">
            <tr>
                <th style="text-align: left; font-weight: 600;"> Name </th>
                <th style="text-align: left; font-weight: 600;"> Name </th>
                <th style="text-align: left; font-weight: 600;"> ID </th>
                <th style="text-align: left; font-weight: 600;"> DOB </th>
                <th style="text-align: left; font-weight: 600;">  </th>
    
            </tr>
        </thead>
        <tbody style="border-bottom: 1px solid black;">
    """
            for recordIndex in 0..<nameArr.count
     {
                
                let  name = (nameArr[recordIndex])
                
                let fatherName = fNameArr[recordIndex]
                let id = idArr[recordIndex]
                var dob = dobArr[recordIndex]
                
                text = text + """
     <tr>
                <td>\(name)</td>
                <td>\(fatherName)</td>
                <td>\(id)</td>
                <td>\(dob)</td>
            </tr>
     """
            }
            
            text = text + """
                </tbody>
                </table>
                """
            return text
        }
        //pic file from phone directory and draw imge there on given Rect
        func drawImageOnPDF(path: String) {
            
            let pdf = CGPDFDocument(NSURL(fileURLWithPath: path))
            let pageCount = pdf?.numberOfPages
            UIGraphicsBeginPDFContextToFile(path, CGRect.zero, nil)
            for index in 1...pageCount! {
                let page =  pdf?.page(at: index)
                let pageFrame = page?.getBoxRect(.mediaBox)
                UIGraphicsBeginPDFPageWithInfo(pageFrame!, nil)
                let ctx = UIGraphicsGetCurrentContext()
                ctx?.saveGState()
                ctx?.scaleBy(x: 1, y: -1)
                ctx?.translateBy(x: 0, y: -pageFrame!.size.height)
                ctx?.drawPDFPage(page!)
                ctx?.restoreGState()
                
                if index == 1 {
                    imageLogo!.draw(in: CGRect(x: 455.2, y: 40, width: 95, height: 65))
                }
                
            }
            UIGraphicsEndPDFContext()
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-09-10
      • 1970-01-01
      • 2016-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多