19
 -(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);
}

上記のコードを使用して、webview から pdf ファイルを生成しています。機能していますが、コンテンツが正しくトリミングされていません。ページの下部にあるコンテンツがめちゃくちゃになります。Core Graphics メソッドを使用してもっと良いことができると思いますが、その方法が見つかりません。何か案は ?

4

6 に答える 6

13

Firemarble さん、ご回答ありがとうございます。大変助かりました。私はこの方法でやや見栄えの良い結果を得ることができました:

-(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];
}
于 2013-04-08T14:09:26.123 に答える
7

@Dan Loewenherzの回答のSwift 3ソリューション:

func webViewDidFinishLoad(_ webView: UIWebView) {
    let pdfData = createPdfFile(printFormatter: webView.viewPrintFormatter())
    pdfData.write(toFile: "/path/to/file", atomically: true)
}

func createPdfFile(printFormatter: UIViewPrintFormatter) -> NSData {
    let renderer = UIPrintPageRenderer()
    renderer.addPrintFormatter(printFormatter, startingAtPageAt: 0)
    let point = CGPoint(x:0,y:0)
    let paperSize = CGSize(width: self.view.frame.size.width, height: self.view.frame.size.height)
    let printableRect = CGRect(origin: point, size: CGSize(width:paperSize.width, height: paperSize.height))
    let paperRect = CGRect(origin: point, size: CGSize(width: paperSize.width, height: paperSize.height))
    renderer.setValue(NSValue(cgRect: paperRect), forKey: "paperRect")
    renderer.setValue(NSValue(cgRect: printableRect), forKey: "printableRect")
    return renderer.printToPDF()
}

extension UIPrintPageRenderer {
    func printToPDF() -> NSData {
        let pdfData = NSMutableData()
        UIGraphicsBeginPDFContextToData(pdfData, self.paperRect, nil)
        self.prepare(forDrawingPages: NSMakeRange(0, self.numberOfPages))
        let bounds = UIGraphicsGetPDFContextBounds()
        for i in 0..<self.numberOfPages {
            UIGraphicsBeginPDFPage();
            self.drawPage(at: i, in: bounds)
        }
        UIGraphicsEndPDFContext();
        return pdfData;
    }
}
于 2017-06-13T06:24:41.980 に答える