Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

One of the best way to convert tableView into mutiple pages PDF in Swift, iOS

Use this function to get mutiple pages pdf Version of your tableView, just pass your tableView name to this function :-

func pdfDataWithTableView(tableView: UITableView) {


        let priorBounds = tableView.bounds
        let fittedSize = tableView.sizeThatFits(CGSizeMake(priorBounds.size.width, tableView.contentSize.height))
        tableView.bounds = CGRectMake(0, 0, fittedSize.width, fittedSize.height)
        let pdfPageBounds = CGRectMake(0, 0, tableView.frame.width, self.view.frame.height)
        let pdfData = NSMutableData()
        UIGraphicsBeginPDFContextToData(pdfData, pdfPageBounds,nil)
        var pageOriginY: CGFloat = 0
        while pageOriginY < fittedSize.height {
            UIGraphicsBeginPDFPageWithInfo(pdfPageBounds, nil)
            CGContextSaveGState(UIGraphicsGetCurrentContext())
            CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0, -pageOriginY)
            tableView.layer.renderInContext(UIGraphicsGetCurrentContext()!)
            CGContextRestoreGState(UIGraphicsGetCurrentContext())
            pageOriginY += pdfPageBounds.size.height
        }
        UIGraphicsEndPDFContext()
        tableView.bounds = priorBounds

        var docURL = (NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)).last! as NSURL
        docURL = docURL.URLByAppendingPathComponent( "myDocument.pdf")
        pdfData.writeToURL(docURL, atomically: true)
    }
like image 713
Himanshu Avatar asked Sep 02 '16 09:09

Himanshu


2 Answers

Update with swift

   func pdfDataWithTableView(tableView: UITableView) {    
        let priorBounds = tableView.bounds
        let fittedSize = tableView.sizeThatFits(CGSize(width:priorBounds.size.width, height:tableView.contentSize.height))
        tableView.bounds = CGRect(x:0, y:0, width:fittedSize.width, height:fittedSize.height)
        let pdfPageBounds = CGRect(x:0, y:0, width:tableView.frame.width, height:self.view.frame.height)    
        let pdfData = NSMutableData()
        UIGraphicsBeginPDFContextToData(pdfData, pdfPageBounds,nil)
        var pageOriginY: CGFloat = 0
        while pageOriginY < fittedSize.height {
            UIGraphicsBeginPDFPageWithInfo(pdfPageBounds, nil)
            UIGraphicsGetCurrentContext()!.saveGState()
            UIGraphicsGetCurrentContext()!.translateBy(x: 0, y: -pageOriginY)
            tableView.layer.render(in: UIGraphicsGetCurrentContext()!)
            UIGraphicsGetCurrentContext()!.restoreGState()
            pageOriginY += pdfPageBounds.size.height
        }
        UIGraphicsEndPDFContext()
        tableView.bounds = priorBounds
        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)
    }
like image 67
Raj Joshi Avatar answered Nov 01 '22 11:11

Raj Joshi


In order to make Raj Joshi solution render the whole table with different cell heights, you need to change content offset of the table view on each render cycle.

The full snippet:

func pdfDataWithTableView(tableView: UITableView) {    
  let priorBounds = tableView.bounds

  let fittedSize = tableView.sizeThatFits(CGSize(
    width: priorBounds.size.width, 
    height: tableView.contentSize.height
  ))

  tableView.bounds = CGRect(
    x: 0, y: 0,
    width: fittedSize.width,
    height: fittedSize.height
  )

  let pdfPageBounds = CGRect(
    x :0, y: 0,
    width: tableView.frame.width, 
    height: self.view.frame.height
  )    

  let pdfData = NSMutableData()
  UIGraphicsBeginPDFContextToData(pdfData, pdfPageBounds, nil)

  var pageOriginY: CGFloat = 0
  while pageOriginY < fittedSize.height {
    UIGraphicsBeginPDFPageWithInfo(pdfPageBounds, nil)
    UIGraphicsGetCurrentContext()!.saveGState()
    UIGraphicsGetCurrentContext()!.translateBy(x: 0, y: -pageOriginY)
    tableView.layer.render(in: UIGraphicsGetCurrentContext()!)
    UIGraphicsGetCurrentContext()!.restoreGState()
    pageOriginY += pdfPageBounds.size.height
    tableView.contentOffset = CGPoint(x: 0, y: pageOriginY) // move "renderer"
  }
  UIGraphicsEndPDFContext()

  tableView.bounds = priorBounds
  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)
}
like image 2
inokey Avatar answered Nov 01 '22 09:11

inokey