-(void)createPDFfromUIView:(UIView*)aView saveToDocumentsWithFileName:(NSString*)aFilename
{
// Creates a mutable data object for updating with binary data, like a byte array
UIWebView *webView = (UIWebView*)aView;
NSString *heightStr = [webView stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight;"];
int height = [heightStr intValue];
// Get the number of pages needed to print. 9 * 72 = 648
int pages = ceil(height / 648.0);
NSMutableData *pdfData = [NSMutableData data];
UIGraphicsBeginPDFContextToData( pdfData, CGRectZero, nil );
CGRect frame = [webView frame];
for (int i = 0; i < pages; i++) {
// Check to see if page draws more than the height of the UIWebView
if ((i+1) * 648 > height) {
CGRect f = [webView frame];
f.size.height -= (((i+1) * 648.0) - height);
[webView setFrame: f];
}
UIGraphicsBeginPDFPage();
CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(currentContext, 72, 72); // Translate for 1" margins
[[[webView subviews] lastObject] setContentOffset:CGPointMake(0, 648 * i) animated:NO];
[webView.layer renderInContext:currentContext];
}
UIGraphicsEndPDFContext();
// Retrieves the document directories from the iOS device
NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
NSString* documentDirectory = [documentDirectories objectAtIndex:0];
NSString* documentDirectoryFilename = [documentDirectory stringByAppendingPathComponent:aFilename];
// instructs the mutable data object to write its context to a file on disk
[pdfData writeToFile:documentDirectoryFilename atomically:YES];
[webView setFrame:frame];
NSLog(@"documentDirectoryFileName: %@",documentDirectoryFilename);
}
I'm using the code above to generate a pdf file from a webview. It's working, however, the content is not cropped correctly : the content on the bottom of the pages get messed up. I think I could do something better using Core Graphics methods but I can't find how to do that. Any ideas ?
Use UIPrintPageRenderer
from UIWebView
Follow below steps :
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
#define kPaperSizeA4 CGSizeMake(595.2,841.8)
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");
}
}
Thank you for your answers Firemarble, it helped me a lot. I managed to get a somewhat good looking results with this method :
-(void)createPDFfromUIView:(UIView*)aView saveToDocumentsWithFileName:(NSString*)aFilename
{
// Creates a mutable data object for updating with binary data, like a byte array
UIWebView *webView = (UIWebView*)aView;
NSString *heightStr = [webView stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight;"];
int height = [heightStr intValue];
// CGRect screenRect = [[UIScreen mainScreen] bounds];
// CGFloat screenHeight = (self.contentWebView.hidden)?screenRect.size.width:screenRect.size.height;
CGFloat screenHeight = webView.bounds.size.height;
int pages = ceil(height / screenHeight);
NSMutableData *pdfData = [NSMutableData data];
UIGraphicsBeginPDFContextToData(pdfData, webView.bounds, nil);
CGRect frame = [webView frame];
for (int i = 0; i < pages; i++) {
// Check to screenHeight if page draws more than the height of the UIWebView
if ((i+1) * screenHeight > height) {
CGRect f = [webView frame];
f.size.height -= (((i+1) * screenHeight) - height);
[webView setFrame: f];
}
UIGraphicsBeginPDFPage();
CGContextRef currentContext = UIGraphicsGetCurrentContext();
[[[webView subviews] lastObject] setContentOffset:CGPointMake(0, screenHeight * i) animated:NO];
[webView.layer renderInContext:currentContext];
}
UIGraphicsEndPDFContext();
// Retrieves the document directories from the iOS device
NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
NSString* documentDirectory = [documentDirectories objectAtIndex:0];
NSString* documentDirectoryFilename = [documentDirectory stringByAppendingPathComponent:aFilename];
// instructs the mutable data object to write its context to a file on disk
[pdfData writeToFile:documentDirectoryFilename atomically:YES];
[webView setFrame:frame];
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With