SpreadsheetView icon indicating copy to clipboard operation
SpreadsheetView copied to clipboard

Export to PDF

Open spydercapriani opened this issue 5 years ago • 7 comments

Enhancement

Provide functionality to allow spreadsheet view to be exported to PDF.

Use Cases

  • Printing
  • Saving
  • Sharing

spydercapriani avatar Aug 17 '18 16:08 spydercapriani

Not an issue but suggestion / enhancement. I will attempt to enable this but wanted to bring this up in case it was already an available option.

spydercapriani avatar Aug 17 '18 16:08 spydercapriani

Use this function to export SpreadsheetView as PDF.

func createPdfFromView()
    {
        // Set frame as per content of view

        self.spreadsheetView.frame = CGRect(x: 0, y: 0, width: self.spreadsheetView.contentSize.width, height: self.spreadsheetView.contentSize.height)
        let pdfPageBounds: CGRect = self.spreadsheetView.frame
        let pdfData: NSMutableData = NSMutableData()

        // Rendering spreadsheetView
        UIGraphicsBeginPDFContextToData(pdfData, pdfPageBounds, nil)
        UIGraphicsBeginPDFPageWithInfo(pdfPageBounds, nil)
        self.spreadsheetView.layer.render(in: UIGraphicsGetCurrentContext()!)
        UIGraphicsEndPDFContext()
        let documentDirectories = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first
        let documentsFileName = documentDirectories! + "/" + "pdfName.pdf"
        pdfData.write(toFile: documentsFileName, atomically: true)
        print(documentsFileName)

        // Reset spreadsheetView
        self.spreadsheetView.frame = CGRect(x: 0, y: 64, width: self.view.frame.width, height: self.view.frame.height)
        self.spreadsheetView.layoutSubviews()
        self.spreadsheetView.layoutIfNeeded()
        self.spreadsheetView.reloadData()}
}

arpitjain03 avatar Feb 13 '20 11:02 arpitjain03

I couldn't get the whole content view as pdf, only the visible rect.

yodagamaheshan avatar Mar 26 '20 12:03 yodagamaheshan

Export to Excel file would also be amazing.

isaranjha avatar Oct 19 '20 12:10 isaranjha

I couldn't get the whole content view as pdf, only the visible rect.

Me too

imnayandave avatar Mar 15 '22 09:03 imnayandave

To be honest, this has alot of guess work. If anyone can figure out how to get the width of the frozen cells, because calling spreadsheetView.cellForRowAt() doesn't always return the cell. Instead I just have correcters to fix the problem. I've been working on a new spreadsheetView at https://github.com/BTAProgrammers/SpreadsheetView which I'll probably implement in. However this works for capturing more than the visible rect.

    let priorBounds = spreadsheetView.bounds

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

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

    let pdfPageBounds = CGRect(
      x :0, y: 0,
      width: spreadsheetView.contentSize.width,
      height: spreadsheetView.contentSize.height
    )

    var colFrozenCorrection : CGFloat = 5
    var rowFrozenCorrection : CGFloat = 5

    for i in 0..<spreadsheetView.frozenColumns {
        colFrozenCorrection += spreadsheetView.rectForItem(at: IndexPath(row: 0, column: i)).width
    }
            
    for i in 0..<spreadsheetView.frozenRows {
        rowFrozenCorrection += spreadsheetView.rectForItem(at: IndexPath(row: i, column: 0)).height
    }
    

    let pdfData = NSMutableData()
    UIGraphicsBeginPDFContextToData(pdfData, pdfPageBounds, nil)
    
    UIGraphicsBeginPDFPageWithInfo(pdfPageBounds, nil)
    
    for j in 1...Int(floor(pdfPageBounds.height / fittedSize.height))+1 {
        for i in 1...Int(floor(pdfPageBounds.width / fittedSize.width))+1 {
            spreadsheetView.contentOffset = CGPoint(x:  i == Int(floor(pdfPageBounds.width / fittedSize.width))+1 ? 0 : i != 1 ? (pdfPageBounds.width - (fittedSize.width * CGFloat(i))) + colFrozenCorrection : (pdfPageBounds.width - (fittedSize.width * CGFloat(i))), y: j == Int(floor(pdfPageBounds.height / fittedSize.height))+1 ? 0 : j != 1 ? pdfPageBounds.height - (fittedSize.height * CGFloat(j)) + rowFrozenCorrection : pdfPageBounds.height - (fittedSize.height * CGFloat(j)))
            UIGraphicsGetCurrentContext()!.saveGState()
            UIGraphicsGetCurrentContext()!.translateBy(x: i == Int(floor(pdfPageBounds.width / fittedSize.width))+1 ? 0 : i != 1 ? (pdfPageBounds.width - (fittedSize.width * CGFloat(i))) + colFrozenCorrection : (pdfPageBounds.width - (fittedSize.width * CGFloat(i))), y: j == Int(floor(pdfPageBounds.height / fittedSize.height))+1 ? 0 : j != 1 ? pdfPageBounds.height - (fittedSize.height * CGFloat(j)) + rowFrozenCorrection : pdfPageBounds.height - (fittedSize.height * CGFloat(j)))
            spreadsheetView.layer.render(in: UIGraphicsGetCurrentContext()!)
            UIGraphicsGetCurrentContext()!.restoreGState()
        }
    }
    
    UIGraphicsEndPDFContext()

    let documentDirectories = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first
    let documentsFileName = documentDirectories! + "/" + "pdfName.pdf"
    pdfData.write(toFile: documentsFileName, atomically: true)
    print(documentsFileName)

Edit: Solved frozen cell issue

FadyFaheem avatar Feb 06 '23 14:02 FadyFaheem

For people who see my example above, I've also implemented exporting to pdf in my version of SpreadsheetView. Link is here if you'd like to use it. I haven't pushed it into a branch release, but it will come later. you can pull my version via the main branch instead of release.

FadyFaheem avatar Feb 06 '23 15:02 FadyFaheem