This question already has answers here:
Creating PDF file from UIWebView
(6 answers)
Closed 5 years ago.
how to create UIWebView Content as pdf file..?
i followed this link but this one not creating the entire webview content(still have some data on webview when i scroll) it is only creating a pdf what the screen is showing..
How to Convert UIView to PDF within iOS?
any help
Use UIPrintPageRenderer from UIWebView Follow below steps :
Add Category of UIPrintPageRenderer for getting PDF Data
#interface UIPrintPageRenderer (PDF)
- (NSData*) printToPDF;
#end
#implementation UIPrintPageRenderer (PDF)
- (NSData*) printToPDF
{
NSMutableData *pdfData = [NSMutableData data];
UIGraphicsBeginPDFContextToData( pdfData, self.paperRect, nil );
[self prepareForDrawingPages: NSMakeRange(0, self.numberOfPages)];
CGRect bounds = UIGraphicsGetPDFContextBounds();
for ( int i = 0 ; i < self.numberOfPages ; i++ )
{
UIGraphicsBeginPDFPage();
[self drawPageAtIndex: i inRect: bounds];
}
UIGraphicsEndPDFContext();
return pdfData;
}
#end
Add these define for A4 size
#define kPaperSizeA4 CGSizeMake(595.2,841.8)
Now in UIWebView's webViewDidFinishLoad delegate use UIPrintPageRenderer property of UIWebView.
- (void)webViewDidFinishLoad:(UIWebView *)awebView
{
if (awebView.isLoading)
return;
UIPrintPageRenderer *render = [[UIPrintPageRenderer alloc] init];
[render addPrintFormatter:awebView.viewPrintFormatter startingAtPageAtIndex:0];
//increase these values according to your requirement
float topPadding = 10.0f;
float bottomPadding = 10.0f;
float leftPadding = 10.0f;
float rightPadding = 10.0f;
CGRect printableRect = CGRectMake(leftPadding,
topPadding,
kPaperSizeA4.width-leftPadding-rightPadding,
kPaperSizeA4.height-topPadding-bottomPadding);
CGRect paperRect = CGRectMake(0, 0, kPaperSizeA4.width, kPaperSizeA4.height);
[render setValue:[NSValue valueWithCGRect:paperRect] forKey:#"paperRect"];
[render setValue:[NSValue valueWithCGRect:printableRect] forKey:#"printableRect"];
NSData *pdfData = [render printToPDF];
if (pdfData) {
[pdfData writeToFile:[NSString stringWithFormat:#"%#/tmp.pdf",NSTemporaryDirectory()] atomically: YES];
}
else
{
NSLog(#"PDF couldnot be created");
}
}
You're right, you need a Webview.
If you have the .pdf file in the bundle, simply do this :
#implementation{
UIWebView *documentWebView;
}
- (void)viewDidLoad{ //Or any other method that you want to create the webview with.
//Getting the full screen size
UIWindow* currentWindow = [UIApplication sharedApplication].keyWindow;
CGRect fullScreenRect = currentWindow.bounds;
//Getting the pdf from the bundle ; change filepath with URL if its from the internet
filePath = [[NSBundle mainBundle] pathForResource:#"YourPDFFileName" ofType:#"pdf"];
NSURL *fileURL = [NSURL fileURLWithPath:filePath];
NSURLRequest *request = [NSURLRequest requestWithURL:fileURL];
//Creating the view programatically, because I'm like that.
documentWebView = [[UIWebView alloc] initWithFrame:CGRectMake(fullScreenRect.origin.x, fullScreenRect.origin.y, fullScreenRect.size.width, fullScreenRect.size.height)];
documentWebView.scalesPageToFit = YES;
//Setting a back button to dismiss the view.
UIButton *backButton = [[UIButton alloc]initWithFrame:CGRectMake(fullScreenRect.size.width-115, 10, 100, 30)];
backButton.backgroundColor = [UIColor grayColor];
backButton.alpha = 0.8;
[backButton setTitle:#"Back" forState:UIControlStateNormal];
//Linking the action & the button
[backButton addTarget:self action:#selector(closeWebView:) forControlEvents:UIControlEventTouchUpInside];
//Loading the pdf into the actual view
[documentWebView loadRequest:request];
//Adding the views to the main view
[currentWindow addSubview:documentWebView];
[documentWebView addSubview:backButton];
}
//Dismissing the view
- (IBAction)closeWebView:(id)sender{
[documentWebView removeFromSuperview];
[documentWebView release];
}
Related
i want to save pdf to ibook from UIWebView in the app, the html in UIWebView can be multi page.
i try using
NSString *page = [self.lowWebview stringByEvaluatingJavaScriptFromString:#"document.body.outerHTML"];
NSString *path = [self exportHTMLContentToPDF:page];
NSURL *targetURL = [NSURL fileURLWithPath:path];
self.docController = [UIDocumentInteractionController interactionControllerWithURL:targetURL];
if([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:#"itms-books:"]])
{
[self.docController presentOpenInMenuFromRect:CGRectZero inView:self.view animated:YES];
NSLog(#"iBooks installed");
} else {
NSLog(#"iBooks not installed");
}
exportHTMLContentToPDF:
CustomPrintPageRenderer *printPageRenderer = [[CustomPrintPageRenderer alloc] init];
UIMarkupTextPrintFormatter *printFormatter = [[UIMarkupTextPrintFormatter alloc] initWithMarkupText:HTMLContent];
[printPageRenderer addPrintFormatter:printFormatter startingAtPageAtIndex:0];//.addPrintFormatter(printFormatter, startingAtPageAtIndex: 0)
NSData *pdfData = [self drawPDFUsingPrintPageRenderer:printPageRenderer];
NSString *docDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *fileName = [docDirPath stringByAppendingPathComponent:#"ticket.pdf"];
[pdfData writeToFile:fileName atomically:true];//.writeToFile(fileName, atomically: true)
NSLog(#"%#", fileName);
return fileName;
the problem is exportHTMLContentToPDF create just one page if UIWebView contain multiple page, and some time the output format is not well print in pdf
thanks in advance.
Create PDF from any Microsoft Document loaded in UIWebview
#define kPaperSizeA4 CGSizeMake(595.2,841.8)
First of all implement UIPrintPageRenderer protocol
#interface UIPrintPageRenderer (PDF)
- (NSData*) printToPDF;
#end
#implementation UIPrintPageRenderer (PDF)
- (NSData*) printToPDF
{
NSMutableData *pdfData = [NSMutableData data];
UIGraphicsBeginPDFContextToData( pdfData, self.paperRect, nil );
[self prepareForDrawingPages: NSMakeRange(0, self.numberOfPages)];
CGRect bounds = UIGraphicsGetPDFContextBounds();
for ( int i = 0 ; i < self.numberOfPages ; i++ )
{
UIGraphicsBeginPDFPage();
[self drawPageAtIndex: i inRect: bounds];
}
UIGraphicsEndPDFContext();
return pdfData;
}
#end
Then, call below method after document finished loading in UIWebView
-(void)createPDF:(UIWebView *)webView {
UIPrintPageRenderer *render = [[UIPrintPageRenderer alloc] init];
[render addPrintFormatter:webView.viewPrintFormatter startingAtPageAtIndex:0];
float padding = 10.0f;
CGRect paperRect = CGRectMake(0, 0, kPaperSizeA4.width, kPaperSizeA4.height);
CGRect printableRect = CGRectMake(padding, padding, kPaperSizeA4.width-(padding * 2), kPaperSizeA4.height-(padding * 2));
[render setValue:[NSValue valueWithCGRect:paperRect] forKey:#"paperRect"];
[render setValue:[NSValue valueWithCGRect:printableRect] forKey:#"printableRect"];
NSData *pdfData = [render printToPDF];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if (pdfData) {
[pdfData writeToFile:directoryPath atomically: YES];
}
else
{
NSLog(#"PDF couldnot be created");
}
});}
Excerpted from PDF Creation in iOS - Create PDF from any Microsoft Document loaded in UIWebview. The original author was Mansi Panchal. Attribution details can be found on the contributor page. The source is licenced under CC BY-SA 3.0 and may be found in the Documentation archive. Reference topic ID: 2416 and example ID: 28437.
#define kPaperSizeA4 CGSizeMake(595.2,841.8)
First of all implement UIPrintPageRenderer protocol
#interface UIPrintPageRenderer (PDF)
- (NSData*) printToPDF;
#end
#implementation UIPrintPageRenderer (PDF)
- (NSData*) printToPDF
{
NSMutableData *pdfData = [NSMutableData data];
UIGraphicsBeginPDFContextToData( pdfData, self.paperRect, nil );
[self prepareForDrawingPages: NSMakeRange(0, self.numberOfPages)];
CGRect bounds = UIGraphicsGetPDFContextBounds();
for ( int i = 0 ; i < self.numberOfPages ; i++ )
{
UIGraphicsBeginPDFPage();
[self drawPageAtIndex: i inRect: bounds];
}
UIGraphicsEndPDFContext();
return pdfData;
}
#end
Then, call below method after document finished loading in UIWebView
-(void)createPDF:(UIWebView *)webView {
UIPrintPageRenderer *render = [[UIPrintPageRenderer alloc] init];
[render addPrintFormatter:webView.viewPrintFormatter startingAtPageAtIndex:0];
float padding = 10.0f;
CGRect paperRect = CGRectMake(0, 0, kPaperSizeA4.width, kPaperSizeA4.height);
CGRect printableRect = CGRectMake(padding, padding, kPaperSizeA4.width-(padding * 2), kPaperSizeA4.height-(padding * 2));
[render setValue:[NSValue valueWithCGRect:paperRect] forKey:#"paperRect"];
[render setValue:[NSValue valueWithCGRect:printableRect] forKey:#"printableRect"];
NSData *pdfData = [render printToPDF];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if (pdfData) {
[pdfData writeToFile:directoryPath atomically: YES];
}
else
{
NSLog(#"PDF couldnot be created");
} });}
Ref: https://medium.com/#javedmultani16/create-pdf-from-any-microsoft-document-loaded-in-uiwebview-in-ios-15229671060b
This may help with quality and multi-page issues :
https://coderwall.com/p/gssuka/rendering-html-pdf-report-for-printing-from-uiwebview
I am try to display a PDF in UIWebView via NSURL. It works fine.
But I do not know the height of pdf document. So sometimes it creates blank space or need to scroll. The PDF may also contain multiple pages.
I only want to show first page if it contain multi pages.
My code is as follow:
NSURL *url = [NSURL URLWithString:#"http://www.eecs.harvard.edu/econcs/pubs/online.pdf"];
NSURLRequest * request = [NSURLRequest requestWithURL:url];
[web_large loadRequest:request];
[web_large setScalesPageToFit:YES];
Right now, the WebView has a fixed height
Pradumna Patil's answer is correct. I combined your code with his, and it worked fine. Just paste the following lines into your project and see for yourself:
UIWebView *web_large = [[UIWebView alloc]init];
[self.view addSubview:web_large];
NSURL *url = [NSURL URLWithString:#"https://www.truthinadvertising.org/wp-content/uploads/2014/09/App-Store-Review-Guidelines.pdf"];
NSURLRequest * request = [NSURLRequest requestWithURL:url];
[web_large loadRequest:request];
[web_large setScalesPageToFit:YES];
CGPDFDocumentRef pdfDocumentRef = CGPDFDocumentCreateWithURL((CFURLRef)url);
CGPDFPageRef pdfPageRef = CGPDFDocumentGetPage(pdfDocumentRef, 1);
CGRect pdfPageRect = CGPDFPageGetBoxRect(pdfPageRef, kCGPDFMediaBox);
float width = pdfPageRect.size.width;
float height = pdfPageRect.size.height;
CGRect screenRect = [[UIScreen mainScreen]bounds];
web_large.frame = CGRectMake(0, 0, screenRect.size.width, height*screenRect.size.width/width);
Try this
There is this method:
size_t CGPDFDocumentGetNumberOfPages(CGPDFDocumentRef document)
That gives you the number of pages.
For ex.
NSURL *pdfUrl = [NSURL fileURLWithPath:yourPath];
CGPDFDocumentRef document = CGPDFDocumentCreateWithURL((CFURLRef)pdfUrl);
Below code gives height of single page in pdf file
float width = CGPDFPageGetBoxRect(pdfPageRef, kCGPDFMediaBox).size.width;
float height = CGPDFPageGetBoxRect(pdfPageRef, kCGPDFMediaBox).size.height;
Hope it helps.
in Swift you can do:
let documents = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first
let writePath = documents?.appending("/myPdf.pdf")
let pdf: CGPDFDocument! = CGPDFDocument(URL.init(fileURLWithPath: writePath!) as CFURL)`enter code here`
let firstPage: CGPDFPage = pdf.page(at: 1)!
let heightFirstPage :CGRect = firstPage.getBoxRect(.mediaBox)
var heightPagePdf : CGFloat = heightFirstPage.height;
the variable 'pdf' also has a property 'numberOfPages', so you can know the entire height of pdf document (pdf.numberOfPages * heightPagePdf).
best regard
This one is easy.
You have to access the scrollview of the webView not the webview itself:
CGFloat totalHeight = self.webView.scrollView.contentSize.height;
Try this .. Its working fine
NSURL* pdfFileUrl = targetURL;
CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL((CFURLRef)pdfFileUrl);
CGFloat pdfHeight = 0;
NSUInteger totalNum = CGPDFDocumentGetNumberOfPages(pdf);
for(int i = 0; i < totalNum; i++ ) {
CGPDFPageRef myPageRef=CGPDFDocumentGetPage(pdf, i+1);
CGRect cropBox = CGPDFPageGetBoxRect(myPageRef, kCGPDFCropBox);
pdfHeight+=cropBox.size.height;
int pageRotation = CGPDFPageGetRotationAngle(myPageRef);
CGSize pageVisibleSize = CGSizeMake(cropBox.size.width, cropBox.size.height);
if ((pageRotation == 90) || (pageRotation == 270) ||(pageRotation == -90)) {
pageVisibleSize = CGSizeMake(cropBox.size.height, cropBox.size.width);
}
}
NSLog(#"%f",pdfHeight);
Instead of loading pdf in webView I would like to suggest you to draw PDF in UIView, Like I have done in my own project and it's working perfect.
Below is mine UIView subClass which draw pdf in UIView context.
PDFPage.h
#import <UIKit/UIKit.h>
#protocol PDFPageDelegate;
#interface PDFPage : UIView
#property uint currentPage;
#property unsigned long totalPages;
#property CGRect pageRect;
#property NSString *pdfPath;
#property id<PDFPageDelegate> delegate;
- (CGRect)setPdf:(NSString*)filePath;
- (void)swipeLeft;
- (void)swipeRight;
- (void)setPageNumber:(NSUInteger )targetPageNumber;
#end
#protocol PDFPageDelegate <NSObject>
- (void)pdfWillSwipeToLeft:(uint)upcommingPageNumber;
- (void)pdfWillSwipeToRight:(uint)upcommingPageNumber;
- (void)pdfTaped:(CGPoint)tapAt;
- (void)pdfDoubleTapped;
#end
PDFPage.m
#import "PDFPage.h"
#implementation PDFPage
#synthesize pageRect = _pageRect;
#synthesize currentPage = _currentPage;
#synthesize totalPages = _totalPages;
#synthesize delegate = _delegate;
#synthesize pdfPath = _pdfPath;
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {}
_currentPage = 1;
UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeLeft)];
swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
[self addGestureRecognizer:swipeLeft];
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeRight)];
swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
[self addGestureRecognizer:swipeRight];
return self;
}
- (void)setPageNumber:(NSUInteger )targetPageNumber
{
_currentPage = (uint)targetPageNumber;
[self setNeedsDisplay];
[UIView transitionWithView:self duration:0.5
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
[self.layer displayIfNeeded];
} completion:nil];
}
- (void)swipeLeft
{
if(_currentPage == _totalPages)
return;
_currentPage++;
[_delegate pdfWillSwipeToLeft:_currentPage];
[self setNeedsDisplay];
[UIView transitionWithView:self duration:0.5
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
[self.layer displayIfNeeded];
} completion:nil];
}
- (void)swipeRight
{
if(_currentPage == 1)
return;
_currentPage--;
[_delegate pdfWillSwipeToRight:_currentPage];
[self setNeedsDisplay];
[UIView transitionWithView:self duration:0.5
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
[self.layer displayIfNeeded];
} completion:nil];
}
- (void)drawRect:(CGRect)rect
{
CGContextRef ctx = UIGraphicsGetCurrentContext();
// PDF might be transparent, assume white paper
[[UIColor whiteColor] set];
CGContextFillRect(ctx, rect);
// Flip coordinates
CGContextGetCTM(ctx);
CGContextScaleCTM(ctx, 1, -1);
CGContextTranslateCTM(ctx, 0, -rect.size.height);
// url is a file URL
CFURLRef pdfURL = (__bridge CFURLRef)[NSURL fileURLWithPath:_pdfPath];
CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL(pdfURL);
CGPDFPageRef page1 = CGPDFDocumentGetPage(pdf, _currentPage);
// get the rectangle of the cropped inside
CGRect mediaRect = CGPDFPageGetBoxRect(page1, kCGPDFCropBox);
CGContextScaleCTM(ctx, rect.size.width / mediaRect.size.width,
rect.size.height / mediaRect.size.height);
CGContextTranslateCTM(ctx, -mediaRect.origin.x, -mediaRect.origin.y);
// draw it
CGContextDrawPDFPage(ctx, page1);
CGPDFDocumentRelease(pdf);
}
- (CGRect)setPdf:(NSString*)filePath
{
_pdfPath =filePath;
_currentPage = 1;
CFURLRef pdfURL = (__bridge CFURLRef)[NSURL fileURLWithPath:_pdfPath];
CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL(pdfURL);
CGPDFPageRef page = CGPDFDocumentGetPage(pdf,_currentPage);
_pageRect = CGPDFPageGetBoxRect(page, kCGPDFCropBox);
_totalPages = (CGPDFDocumentGetNumberOfPages(pdf));
[self setNeedsDisplay];
[UIView transitionWithView:self duration:0.5
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
[self setNeedsDisplay];
} completion:nil];
CGRect finalRect = CGRectMake(0, 0, _pageRect.size.width, _pageRect.size.height);
return finalRect;
}
How to use:-
NSData *pdfData = [NSData dataWithContentsOfURL:[NSURL URLWithString:pdfPath]]; // here pdfPath is webURL
NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * savePDFAt = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
savePDFAt = [NSString stringWithFormat:#"%#/PDFs/",savePDFAt];
[[NSFileManager defaultManager] createDirectoryAtPath:savePDFAt withIntermediateDirectories:NO attributes:nil error:nil];
[savePDFAt stringByAppendingPathComponent:"test.pdf"];
if([pdfData writeToFile:savePDFAt options:0 error:&error])
NSLog(#"PDF download complete");
PDFPage *pdfPage = [PDFPage new];
pdfPage.alpha = 0.0f;
pdfPage.delegate = self;
pdfPage.frame = [pdfPage setPdf:pdfPath];
Then add this pdfPage to self's view or to scroller.
I used web view to load pdf also added an image as subview to my pdfView.
To save the final PDF with subviews,i tried the approach given in the below stack question, it meets the objective but it completely lost quality of the PDF
How to Convert UIView to PDF within iOS?
Now i am try with the below approach,
-(void)savePDFFromWebView:(UIWebView*)webView fileName:(NSString*)_fileName
{
int height, width, header, sidespace;
height = webView.scrollView.contentSize.height;
width = webView.scrollView.contentSize.width;
header = 15;
sidespace = 30;
// set header and footer spaces
UIEdgeInsets pageMargins = UIEdgeInsetsMake(header, sidespace, header, sidespace);
webView.viewPrintFormatter.contentInsets = pageMargins;
UIPrintPageRenderer *renderer = [[UIPrintPageRenderer alloc] init];
[renderer addPrintFormatter:webView.viewPrintFormatter startingAtPageAtIndex:0];
CGSize pageSize = CGSizeMake(width, height);
CGRect printableRect = CGRectMake(pageMargins.left,
pageMargins.top,
pageSize.width - pageMargins.left - pageMargins.right,
pageSize.height - pageMargins.top - pageMargins.bottom);
CGRect paperRect = CGRectMake(0, 0, pageSize.width, pageSize.height);
[renderer setValue:[NSValue valueWithCGRect:paperRect] forKey:#"paperRect"];
[renderer setValue:[NSValue valueWithCGRect:printableRect]
forKey:#"printableRect"];
NSData *pdfData = [self printToPDFWithRenderer:renderer paperRect:paperRect];
// save PDF file
NSString *saveFileName = [NSString stringWithFormat:#"%#%dx%d.pdf",
_fileName, (int)pageSize.width, (int)pageSize.height];
NSString *savePath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)
objectAtIndex:0] stringByAppendingPathComponent:saveFileName];
[pdfData writeToFile: savePath atomically: YES];
}
-(NSData*) printToPDFWithRenderer:(UIPrintPageRenderer*)renderer paperRect:(CGRect)paperRect
{
NSMutableData *pdfData = [NSMutableData data];
UIGraphicsBeginPDFContextToData( pdfData, paperRect, nil );
[renderer prepareForDrawingPages: NSMakeRange(0, renderer.numberOfPages)];
CGRect bounds = UIGraphicsGetPDFContextBounds();
for ( int i = 0 ; i < renderer.numberOfPages ; i++ )
{
UIGraphicsBeginPDFPage();
[renderer drawPageAtIndex: i inRect: bounds];
}
UIGraphicsEndPDFContext();
return pdfData;
}
Here the webView which pass as an input for UIPrintPageRenderer includes the
subviews but the final pdf does not includes subviews.
How to include subviews to save the final PDF?
Note : UIWebView to PDF working for me.
Now UIView to PDF is also option but wanted to work with below code as same as used to create PDF in UIWebView.
I have done below code so far for UIView's viewPrintFormatter to be able create PDF:
Added Category of UIPrintPageRenderer for getting PDF Data
#interface UIPrintPageRenderer (PDF)
- (NSData*) printToPDF;
#end
#implementation UIPrintPageRenderer (PDF)
- (NSData*) printToPDF
{
NSMutableData *pdfData = [NSMutableData data];
UIGraphicsBeginPDFContextToData( pdfData, self.paperRect, nil );
[self prepareForDrawingPages: NSMakeRange(0, self.numberOfPages)];
CGRect bounds = UIGraphicsGetPDFContextBounds();
for ( int i = 0 ; i < self.numberOfPages ; i++ )
{
UIGraphicsBeginPDFPage();
[self drawPageAtIndex: i inRect: bounds];
}
UIGraphicsEndPDFContext();
return pdfData;
}
#end
Add these define for A4 size
#define kPaperSizeA4 CGSizeMake(595.2,841.8)
Create PDF
UIPrintPageRenderer *render = [[UIPrintPageRenderer alloc] init];
[render addPrintFormatter:self.view.viewPrintFormatter startingAtPageAtIndex:0];
//increase these values according to your requirement
float topPadding = 10.0f;
float bottomPadding = 10.0f;
float leftPadding = 10.0f;
float rightPadding = 10.0f;
CGRect printableRect = CGRectMake(leftPadding,
topPadding,
kPaperSizeA4.width-leftPadding-rightPadding,
kPaperSizeA4.height-topPadding-bottomPadding);
CGRect paperRect = CGRectMake(0, 0, kPaperSizeA4.width, kPaperSizeA4.height);
[render setValue:[NSValue valueWithCGRect:paperRect] forKey:#"paperRect"];
[render setValue:[NSValue valueWithCGRect:printableRect] forKey:#"printableRect"];
NSData *pdfData = [render printToPDF];
if (pdfData) {
[pdfData writeToFile:[NSString stringWithFormat:#"%#/tmp.pdf",NSTemporaryDirectory()] atomically: YES];
}
else
{
NSLog(#"PDF couldnot be created");
}
I am creating an iPad application, in that i have to use different PDF forms. I got some methods to generate PDF files through code using Quartz2D. But I have to write entire forms through code. I may have to update the PDF forms in future, so again I have to write the code. So I heard that there is a component called iTextSharp for .net pdf creation - is there something similar for iOS? So that I can use some XML templates to create the PDF files.
Please help, thanks
I do this in my app using the iOS print subsystem and the UIMarkupTextPrintFormatter. The trick is to write your own custom UIPrintPageRenderer that overrides and returns correct values from paperRect and numberOfPages. You'll add your UIMarkupTextPrintFormatter(s) to your custom UIPrintPageRenderer.
Then, you'll need routines similar to this, in the context of your custom UIPrintPageRenderer:
- (CGRect) paperRect
{
if (!_generatingPdf)
return [super paperRect];
return UIGraphicsGetPDFContextBounds();
}
- (CGRect) printableRect
{
if (!_generatingPdf)
return [super printableRect];
return CGRectInset( self.paperRect, 20, 20 );
}
- (NSData*) printToPDF
{
_generatingPdf = YES;
NSMutableData *pdfData = [NSMutableData data];
UIGraphicsBeginPDFContextToData( pdfData, CGRectMake(0, 0, 792, 612), nil ); // letter-size, landscape
[self prepareForDrawingPages: NSMakeRange(0, 1)];
CGRect bounds = UIGraphicsGetPDFContextBounds();
for ( int i = 0 ; i < self.numberOfPages ; i++ )
{
UIGraphicsBeginPDFPage();
[self drawPageAtIndex: i inRect: bounds];
}
UIGraphicsEndPDFContext();
_generatingPdf = NO;
// NSString* filename = #"/Volumes/Macintosh HD 2/test.pdf";
// [pdfData writeToFile: filename atomically: YES];
return pdfData;
}
#TomSwift : agree with his answer but i would like to explain in better way
To be able create PDF from UIWebView is load HTML to yourWebView or there might be case yourWebView can also be hidden to generate PDF but process remains the same
1) Added Category of UIPrintPageRenderer for getting PDF Data as yourWebView.viewPrintFormatter need to be used
#interface UIPrintPageRenderer (PDF)
- (NSData*) printToPDF;
#end
#implementation UIPrintPageRenderer (PDF)
- (NSData*) printToPDF
{
NSMutableData *pdfData = [NSMutableData data];
UIGraphicsBeginPDFContextToData( pdfData, self.paperRect, nil );
[self prepareForDrawingPages: NSMakeRange(0, self.numberOfPages)];
CGRect bounds = UIGraphicsGetPDFContextBounds();
for ( int i = 0 ; i < self.numberOfPages ; i++ )
{
UIGraphicsBeginPDFPage();
[self drawPageAtIndex: i inRect: bounds];
}
UIGraphicsEndPDFContext();
return pdfData;
}
#end
2) Add these define for A4 size or any custom size you want
#define kPaperSizeA4 CGSizeMake(595.2,841.8)
3) Process how we can create PDF
//create print renderer
UIPrintPageRenderer *render = [[UIPrintPageRenderer alloc] init];
[render addPrintFormatter:yourWebView.viewPrintFormatter startingAtPageAtIndex:0];
//provide padding ---- increase these values according to your requirement
float topPadding = 10.0f;
float bottomPadding = 10.0f;
float leftPadding = 10.0f;
float rightPadding = 10.0f;
//provide rect for printing and for actual PDF Rect of page
CGRect printableRect = CGRectMake(leftPadding,
topPadding,
kPaperSizeA4.width-leftPadding-rightPadding,
kPaperSizeA4.height-topPadding-bottomPadding);
CGRect paperRect = CGRectMake(0, 0, kPaperSizeA4.width, kPaperSizeA4.height);
[render setValue:[NSValue valueWithCGRect:paperRect] forKey:#"paperRect"];
[render setValue:[NSValue valueWithCGRect:printableRect] forKey:#"printableRect"];
//category created above is used here
NSData *pdfData = [render printToPDF];
//Save PDF to directory for usage
if (pdfData) {
[pdfData writeToFile:[NSString stringWithFormat:#"%#/tmp.pdf",NSTemporaryDirectory()] atomically: YES];
}
else
{
NSLog(#"PDF couldnot be created");
}