【问题标题】:Swift - local / server image isn't being loaded in HTML String for pdfSwift - 本地/服务器图像未在 pdf 的 HTML 字符串中加载
【发布时间】:2021-10-02 13:02:35
【问题描述】:

我正在从 HTML 字符串创建 pdf。我添加了带有源的图像标签(实时图像 URL 和本地图像路径。)但在这两种方式中都无法在 pdf 中添加图像。休息文本数据和表格正在工作,但图像不加载。这是我创建 HTML 字符串和创建 PDF 的来源。

extension EstimationVC{
var htmlString: String {
    //let imagePath = Bundle.main.path(forResource: "logo", ofType: "png")!
    var baseStringStart = "<table style=\"height: 20px;\" width=\"100%; padding: 10px;\">   <tbody><tr><td style=\"width: 100%; text-align: center; height: 30px;\">&nbsp;</td></tr></tbody>    <tbody><tr><td style=\"width: 100%; text-align: left;\"><h1>From:  \(params["senderCompany"] as? String ?? "") </h1></td></tr></tbody>                         <tbody><tr><td style=\"width: 100px; height:100px; border: 1px solid black; text-align: left;\"><img src=\"logo.png\"/></td></tr></tbody>                         <tbody><tr><td style=\"width: 100%; text-align: right;\">Preventivo #: \(params["invoiceNo"] as? String ?? "")</td></tr></tbody>    <tbody><tr><td style=\"width: 100%; text-align: right;\">Op. Name: \(params["operatorName"] as? String ?? "")</td></tr></tbody>   <tbody><tr><td style=\"width: 100%; text-align: right;\">Date: \(currentDate)</td></tr></tbody><tbody><tr><td style=\"width: 100%; text-align: center;\"><strong>\(params["companyName"] as? String ?? "")</strong></td></tr></tbody><tbody><tr><td style=\"width: 100%; text-align: center;\">\(params["countryOrRegion"] as? String ?? "")</td></tr></tbody></table></td></tr></tbody></table>          <table style=\"height: 20px; background: #fff;\" width=\"100%;\"><tbody><tr></tr></tbody></table>           <table border=\"1\" width=\"100%\" frame=\"hsides\" rules=\"rows\"><tbody style=\"border: 1px solid black;\"><tr style=\"background: #eee; color: #000;\"><td style=\"padding: 5px; text-align: center;\" width=\"10%\">&nbsp;Code</td><td style=\"padding: 5px; text-align: center;\" width=\"40%\">&nbsp;Description</td><td style=\"padding: 5px; text-align: center;\" width=\"10%\">&nbsp;U.M.</td><td style=\"padding: 5px; text-align: center;\" width=\"10%\">&nbsp;Unit Price</td><td style=\"padding: 5px; text-align: center;\" width=\"10%\">&nbsp;Quantity</td><td style=\"padding: 5px; text-align: center;\" width=\"20%\">&nbsp;Price Without Vat</td></tr></tbody>"
    let rowString = "<tbody><tr><td style=\"padding: 5px;\" width=\"10%\">&nbsp;{code}</td></td><td style=\"padding: 5px; text-align: left;\" width=\"40%\">{description}&nbsp;</td></td><td style=\"padding: 5px; text-align: center;\" width=\"10%\">{um}&nbsp;</td></td><td style=\"padding: 5px; text-align: center;\" width=\"10%\">{unit_price}&nbsp;</td></td><td style=\"padding: 5px; text-align: center;\" width=\"10%\">{quantity}&nbsp;</td></td><td style=\"padding: 5px; text-align: center;\" width=\"20%\">{price_without_vat}&nbsp;</td></tr></tbody>"
    
    for description in selectedDataArr.enumerated(){
        var temp = rowString.replacingOccurrences(of: "{code}", with: selectedCodesArr[description.offset].1)
        temp = temp.replacingOccurrences(of: "{description}", with: description.element.1)
        temp = temp.replacingOccurrences(of: "{um}", with: selectedUMArr[description.offset].1)
        temp = temp.replacingOccurrences(of: "{unit_price}", with: selectedPriceArr[description.offset].1)
        temp = temp.replacingOccurrences(of: "{quantity}", with: String(quantityArr[description.offset]))
        temp = temp.replacingOccurrences(of: "{price_without_vat}", with: String(priceWithoutVatArr[description.offset]))

        baseStringStart.append(temp)
    }
    let baseStringEnd = "</table><table width=\"100%\"><tbody style=\"><tr style=\"color: #000;\"><td style=\"padding: 5px; text-align: right;\" width=\"80%\">&nbsp;<strong>Price Without VAT:</strong> </td><td style=\"padding: 5px; text-align: center;\" width=\"20%\">&nbsp;<strong>\(priceWithoutVatArr.sum())</strong></td></tr>           <tr style=\"color: #000;\"><td style=\"padding: 5px; text-align: right;\" width=\"80%\">&nbsp;<strong>VAT(%): </strong> </td><td style=\"padding: 5px; text-align: center;\" width=\"20%\">&nbsp;<strong>\(params["vat"] as? String ?? "")</strong></td></tr>        <tr style=\"color: #000;\"><td style=\"padding: 5px; text-align: right;\" width=\"80%\">&nbsp;<strong>Total Price:</strong> </td><td style=\"padding: 5px; text-align: center;\" width=\"20%\">&nbsp;<strong>\(totalPriceWithVAT)</strong></td></tr>    <tr style=\"color: #000;\"><td style=\"padding: 5px; text-align: right;\" width=\"80%\">&nbsp;<strong></strong> </td><td style=\"padding: 5px; text-align: center;\" width=\"20%\">&nbsp;<strong></strong></td></tr>     </tbody></table>"
    
    return baseStringStart + baseStringEnd
    
}

}

这是我创建 PDF 的功能。

func createPDF(_ completion:  @escaping(_ fileCreated: Bool)-> ()) {
    let path = Bundle.main.path(forResource: "index", ofType: "html")!
    var HTMLContent = try? String(contentsOfFile: path)

    print(HTMLContent!)
    HTMLContent = HTMLContent?.replacingOccurrences(of: "#bodyData#", with: htmlMainString!)
    
    
    
    let fmt = UIMarkupTextPrintFormatter(markupText: HTMLContent!)
    // 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]

    
        pdfData.write(toFile: "\(documentsPath)/file.pdf", atomically: true)
        completion(true)
    
}

其实这行代码有一些错误。我尝试在此处添加实时图像 url,但这不起作用。

   <tbody><tr><td style=\"width: 100px; height:100px; border: 1px solid black; text-align: left;\"><img src=\"logo.png\"/></td></tr></tbody>  

处理 PDF 中图像徽标的任何解决方案。这是我没有徽标的结果。

【问题讨论】:

    标签: html ios swift pdf


    【解决方案1】:

    还有另一种技术。

    首先,将您的 html 字符串加载到 WKWebView 中。然后获取您的网络视图的viewPrintFormatter() 并将该视图添加到您的UIPrintPageRenderer()。 尚未测试,但在我看来,所有图像都应该在打印之前渲染,所以它应该可以工作。

    let formatter = yourWebView.viewPrintFormatter()
    let printPageRenderer = UIPrintPageRenderer()
    printPageRenderer.addPrintFormatter(formatter, startingAtPageAt: 0)
    

    详情在这里https://www.swiftdevcenter.com/create-pdf-from-uiview-wkwebview-and-uitableview/

    【讨论】:

    • 谢谢,那么如何调整html字符串中的图像标签?
    • 你的意思是css和style属性?
    • 是的。你的意思是我需要将我的 htmlString 加载到 WKWebview。然后是 UIPrintPageRenderer() 的下一个过程,但是 这甚至不会在 webview 中显示图像
    • 您的logo.png 保存在哪里,它是远程图像还是本地图像?请先尝试使用随机远程图像 url,然后使用绝对本地路径。
    • 是的,对 URL 图像也做了同样的事情......没用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-09
    • 2019-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多