Просмотр полного содержимого таблицы для создания файла pdf для печати содержимого - PullRequest
0 голосов
/ 06 мая 2020

Привет, сообщество потока StackOver,

Я работал над задачей, в которой мне нужно преобразовать содержимое таблицы (которая содержит представления заголовков разделов и представления строк в нем) в данные формы pdf, а затем использовать эти данные для печати. Преобразовать содержимое tableView в одну страницу pdf очень просто. Но в приведенном ниже коде я визуализирую видимый контент на одной странице, а затем прокручиваю до следующих строк. Это работает для меня, но заголовок раздела печатается на каждой странице, которая скрывает первую строку каждой страницы. Я пробовал рендерить заголовок раздела отдельно, а затем отдельные ячейки; безуспешно.

Прилагаю сюда код печати. ​​

pdfDataWithTableView - функция используется для генерации данных для печати

`

class ReportGenerateV C : UIViewController {

//Views on the top half of the screen
@IBOutlet weak private var printBtn: UIButton!
@IBOutlet weak private var tblVw: UITableView!
@IBOutlet weak private var emailBtn: UIButton!
@IBOutlet weak private var backBtn: UIButton!
@IBOutlet weak var lblCategory: UILabel!


//Public
var displayCategories: [Category]!
//

// MARK:- View life Cycle
override func viewDidLoad() {
    super.viewDidLoad()
    //Layout settings - Header view for the cells
    let headerNib = UINib.init(nibName: "ReportHeaderView", bundle: Bundle.main)
    tblVw.register(headerNib, forHeaderFooterViewReuseIdentifier: "ReportHeaderView")
}

// MARK: - IB ACTIONS

@IBAction private func backButtonAction(_ sender: Any) {
    self.navigationController?.popViewController(animated: true)
}

@IBAction func printReportingBtnAction(_ sender: Any) {
    self.tblVw.setContentOffset(CGPoint(x: 0,  y: UIApplication.shared.statusBarFrame.height ), animated: true)
    self.printReportPDFViewControllerWithName(self.getUrlOfTableData(self.tblVw))
    self.tblVw.setContentOffset(CGPoint(x: 0,  y: UIApplication.shared.statusBarFrame.height ), animated: true)
}

@IBAction func emailReportingBtnAction(_ sender: Any) {

    let mailComposeVC = MFMailComposeViewController()
    if MFMailComposeViewController.canSendMail() {

        mailComposeVC.mailComposeDelegate = self
        mailComposeVC.setToRecipients(["quantumliferyan@gmail.com","admin@quantumhealthapps.com","jochar48@icloud.com", "mediteckhealingprime@gmail.com"])
        mailComposeVC.setSubject("")
        mailComposeVC.setMessageBody("", isHTML: false)

        mailComposeVC.addAttachmentData(self.pdfDataWithTableView(self.tblVw) as Data, mimeType: "application/pdf", fileName: "result")

        self.present(mailComposeVC, animated: true, completion: nil)

    } else {
        Utilities().showAlert(message: AlertMessagesConsts.kEmailAccountAddAlert.rawValue)
    }
}

private func printReportPDFViewControllerWithName( _ pdfFileNameStr: URL)
{
    if UIPrintInteractionController.canPrint(pdfFileNameStr) {
        let printInfo = UIPrintInfo(dictionary: nil)
        printInfo.jobName = pdfFileNameStr.lastPathComponent
        printInfo.outputType = .photo
        let printController = UIPrintInteractionController.shared
        printController.printInfo = printInfo
        printController.showsNumberOfCopies = false
        printController.printingItem = pdfFileNameStr
        printController.present(animated: true, completionHandler: nil)
    }
}


private func pdfDataWithTableView(_ tableView: UITableView) -> NSMutableData
{
    //

    var priorBounds = tableView.bounds
    let fittedSize = tableView.sizeThatFits(CGSize(width:priorBounds.size.width, height:tableView.contentSize.height))
    let pdfPageBounds = CGRect(x:0, y:0, width:tableView.frame.width, height:tableView.frame.height)
    let pdfData = NSMutableData()
    UIGraphicsBeginPDFContextToData(pdfData, pdfPageBounds,nil)

    var section = 0

    while priorBounds.origin.y < fittedSize.height
    {
        print(tableView.visibleHeaderViews)
        UIGraphicsBeginPDFPageWithInfo(pdfPageBounds, nil)
        UIGraphicsGetCurrentContext()!.saveGState()
        UIGraphicsGetCurrentContext()!.translateBy(x: 0, y: -priorBounds.origin.y)
        tableView.layer.render(in: UIGraphicsGetCurrentContext()!)
        UIGraphicsGetCurrentContext()!.translateBy(x: priorBounds.width, y: -priorBounds.origin.y);
        UIGraphicsGetCurrentContext()!.restoreGState()
        priorBounds.origin.y += pdfPageBounds.size.height

        section = section + 1

        var sectionPriorBounds = priorBounds
        sectionPriorBounds.origin.y -= 63
        tableView.scrollRectToVisible(sectionPriorBounds, animated: false)
    }
    UIGraphicsEndPDFContext()

    return pdfData
}



private func getUrlOfTableData(_ paramTbl: UITableView) -> URL {
    let pdfData = self.pdfDataWithTableView(paramTbl)
    //let pdfData = PdfGenerator.PDFWithScrollView(scrollview: paramTbl)
    var docURL = (FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)).last! as URL
    docURL = docURL.appendingPathComponent("myDocument.pdf")

    pdfData.write(to: docURL as URL, atomically: true)
    return docURL
}


static func fromStoryboardObj(_ storyboard: UIStoryboard = UIStoryboard(name: StoryBoardNameKey.kDoctorSB.rawValue, bundle: nil)) -> ReportGenerateVC
{
    let controller = storyboard.instantiateViewController(withIdentifier: NamesVCs.kReportGenerateVC.rawValue) as! ReportGenerateVC
    return controller
}

}

расширение ReportGenerateV C: UITableViewDelegate, UITableViewDataSource {

func numberOfSections(in tableView: UITableView) -> Int {

    displayCategories.count
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 63
}

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 63   
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    return displayCategories[section].subCatArr.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let systemCell = tableView.dequeueReusableCell(withIdentifier: CellIdentifiersKey.kReportChildCell.rawValue, for: indexPath) as! ReportChildCell

    let subCatData : [SubCategory]! = displayCategories[indexPath.section].subCatArr
    systemCell.setCellInfo(subCatData[indexPath.row])
    return systemCell
}

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

    let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: CellIdentifiersKey.kReportHeaderView.rawValue) as! ReportHeaderView
    headerView.setHeaderInfo(displayCategories[section])

    return headerView
}

}

расширение ReportGenerateV C : MFMailComposeViewControllerDelegate {// MARK: - MFMail compose method fun c mailComposeController (_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeViewController, error: Error?) {Controller.dismiss (animated: true, completion: nil)}}

расширение UITableView {

/// The section header views that are visible in the table view.
var visibleHeaderViews: [UITableViewHeaderFooterView] {

    var headerViews = [UITableViewHeaderFooterView]()

    guard let indexPaths = indexPathsForVisibleRows else { return headerViews }

    for indexPath in indexPaths {
        if let headerView = headerView(forSection: indexPath.section) {
            headerViews.append(headerView)
        }
    }

    return headerViews

}

} `

...