【问题标题】:iOS Create PDF with Dynamic ContentiOS 创建带有动态内容的 PDF
【发布时间】:2023-03-18 13:18:01
【问题描述】:

我想用动态内容制作PDF,比如文本是动态的,图像是动态的,所以取决于课程页面的内容也是动态的,我已经按照这个教程http://code.tutsplus.com/tutorials/generating-pdf-documents--mobile-11265

但本教程中的内容不是动态的。

【问题讨论】:

  • 您想将 HTML 转换为 PDF 吗?
  • 不,我在 DB 中有内容,我想以 pdf 文件的形式发送电子邮件。
  • @NikitaKhandelwal 我可以先在 HTML 中转换我的内容,然后在 pdf 上编写该 html 吗?这可能吗?
  • 动态是什么意思?您在描述中提供的链接具有三个功能,用于添加线条、文本和图像以及您要在 PDF 上添加它们的位置。除此之外你还需要什么?
  • 使用NDHTMLToPDF将HTML转换为PDF

标签: ios objective-c iphone pdf-generation


【解决方案1】:

您可以像这样使用 javaScript 为您的动态值传递值

假设您的 HTML 中有一个键“myKey”

<td><span class="fieldVal" id="myKey"></span></td>

并像这样使用传递值

NSBundle *bundle = [NSBundle mainBundle];
NSURL *indexFileURL = [bundle URLForResource:@"name_of_your_local_html" withExtension:@"html"];
[wbView loadRequest:[NSURLRequest requestWithURL:indexFileURL]];
[wbView stringByEvaluatingJavaScriptFromString:[NSString   stringWithFormat:@"document.getElementById('myKey').innerHTML='%@'",@"myValue"]];

现在为了将 HTML 转换为 PDF,您可以使用这个类

https://github.com/iclems/iOS-htmltopdf/blob/master/NDHTMLtoPDF.h

【讨论】:

    【解决方案2】:

    与 Cocoa 或 Cocoa-Touch 中的任何打印作业一样,处理此问题的最简单方法是首先创建一个 UIView(或 UIViewController)子类来绘制/布局您想要打印的数据。即使您不打算在完成的应用程序的屏幕上显示此视图,您也应该这样做。 (您仍然可以在开发中将它放在屏幕上,以使其看起来像您想要的那样。)对于未知大小的模型,一个非常简单的方法可能是 UITableViewController。使用 Autolayout 或旧的 UIViewAutoResizingMasks 以便此视图可以优雅地调整大小。当然,如果它是 UIViewController 子类,那么您也可以使用界面生成器来完成它。..

    一旦你处于这个位置,绘制到 PDF 是微不足道的

    -(BOOL )writePDFtoPath:(NSString *)filePath{
    
    NSMutableData *pdfData = [NSMutableData data];
    UIGraphicsBeginPDFContextToData(pdfData, CGRectZero, nil);
    //note that because I've passed in CGRectZero for the size the context //comes in its default size
    
     /*
      default pdf..
       8.5 X 11 inch
       612 x 792
       */
    //this is only 72dpi, but its the default. I have a trick where I zoom 
    // out before drawing to improve resolution:
    
    NSInteger numberPages = 3; //work out how many pages you need
    
    
    for (NSInteger page = 0 : page < numberPages : page ++ ){
    
    UIGraphicsBeginPDFPage();
    CGContextRef pdfContext = UIGraphicsGetCurrentContext();
    CGFloat scaleFactor = 3.0;
    CGContextSaveGState(pdfContext);
    CGContextScaleCTM(pdfContext, 1.0/scaleFactor, 1.0/scaleFactor);
    
    
    ///
    /// context size is now (612.0 * 3.0 , 792.0 * 3.0) , i.e. resolution 72.0 * 3.0 dpi..
    
    [self.pdfGeneratingView setFrame: CGRectMake( 0.0, 0.0, 612.0*scaleFactor, 792.0*scaleFactor) ]; //let autolayout make it fit 
    
    //prepare your view for this page
    
    [self.pdfGeneratingView.layer renderInContext:pdfContext];
    CGContextRestoreGState(pdfContext);
    
    }//page drawing loop
    
    
    BOOL success = [pdfData writeToFile:filePath atomically:YES];
    return success;
    }
    

    【讨论】:

      【解决方案3】:

      我也使用了相同的工作正常希望这对你有帮助。

      创建一个块:-

      typedef void (^PdfCompletion)(BOOL status, NSString *filePath, NSArray *fbArr);
      
      -(void)addData
      {
          [MBProgressHUD showHUDAddedTo:self.view animated:YES];
          NSMutableDictionary *contactDict = [[NSMutableDictionary alloc] init];
          [contactDict setObject:contactTextField.text forKey:@"phonenumber"];
          [contactDict setObject:emailTextField.text forKey:@"emailid"];
          [contactDict setObject:userNameLabel.text forKey:@"displayname"];
          [self drawPdf:contactDict completion:^(BOOL status,NSString *filePath,NSArray *fbArr)
           {
               if (status)
               {
                   NSMutableArray *arr;
                   arr = [[NSMutableArray alloc] init];
                   NSData *filedata;
                   filedata = [NSData dataWithContentsOfFile:filePath];
                   double locaTotalFileSize = filedata.length +498;
                   totalFileSize += locaTotalFileSize;
                   NSMutableDictionary *fileDict = [[NSMutableDictionary alloc] init];
                   [fileDict setObject:userPicImageView.image forKey:@"image"];
                   [fileDict setObject:filePath forKey:@"filePath"];
                   [fileDict setObject:@"txt" forKey:@"fileType"];
                   [fileDict setObject:[NSString stringWithFormat:@"%@_%@_%@",@"contact",[self getFbID],[self CurrentSystemTime]] forKey:@"fileName"];
                   [fileDict setObject:@"1" forKey:@"uploadStatus"];
                   [fileDict setObject:@"0 KB/0 KB" forKey:@"fileSizeStatus"];
                   [fileDict setObject:@"0 KB/0 KB" forKey:@"ContentSize"];
                   [arr addObject:fileDict];
                   [self switchToReviewFiles:arr];
                   //////NSLog(@"pdf convrt successfull");
               }
               else
               {
                   //////NSLog(@"Error to convert into pdf");
               }
          }];
      }
      
      
      // Then Call The DrawPDF Method::--
      
      -(void)drawPdf:(NSMutableDictionary *)drawText completion:(PdfCompletion)callback
      {
          NSString* fileName = @"contact_card.txt";
      
          NSArray *arrayPaths =
          NSSearchPathForDirectoriesInDomains(
                                              NSDocumentDirectory,
                                              NSUserDomainMask,
                                              YES);
          NSString *path = [arrayPaths objectAtIndex:0];
          NSString* txtFileName = [path stringByAppendingPathComponent:fileName];
      
          NSData *data = [NSJSONSerialization dataWithJSONObject:drawText options:NSJSONWritingPrettyPrinted error:nil];
          [data writeToFile:txtFileName atomically:YES];
          callback(YES, txtFileName, nil);
      

      【讨论】:

        【解决方案4】:

        我知道这是一个老问题,但现在你会使用PDFKit

        在 Objective-C 中:

        @import PDFKit;
        

        然后:

        PDFDocument *doc = [[PDFDocument alloc] init];
        PDFPage *page = [[PDFPage alloc] init];
        [doc insertPage:page atIndex:0];
        CGRect bounds = [page boundsForBox:kPDFDisplayBoxMediaBox];
        PDFAnnotation *textField = [[PDFAnnotation alloc] initWithBounds:bounds forType:PDFAnnotationSubtypeWidget withProperties:nil];
        textField.widgetFieldType = PDFAnnotationWidgetSubtypeText;
        textField.fontColor = UIColor.whiteColor;
        textField.backgroundColor = UIColor.blueColor;
        textField.font = [UIFont systemFontOfSize:14];
        textField.widgetStringValue = @"WWDC 2017";
        [page addAnnotation:textField];
        
        NSURL *fileURL = [[[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:true error:nil] URLByAppendingPathComponent:@"test.pdf"];
        if (![doc writeToURL:fileURL]) {
            NSLog(@"save failed");
        }
        

        或者,在 Swift 中:

        import PDFKit
        

        还有:

        let doc = PDFDocument()
        let page = PDFPage()
        doc.insert(page, at: 0)
        let bounds = page.bounds(for: .mediaBox)
        let textField = PDFAnnotation(bounds: bounds, forType: .widget, withProperties: nil)
        textField.widgetFieldType = .text
        textField.fontColor = .white
        textField.backgroundColor = .blue
        textField.font = .systemFont(ofSize: 14.0)
        textField.widgetStringValue = "WWDC 2017"
        page.addAnnotation(textField)
        
        let fileURL = try! FileManager.default
            .url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
            .appendingPathComponent("test.pdf")
        
        if !doc.write(to: fileURL) {
            print("save failed")
        }
        

        Introducing PDFKit on iOS,上面的sn-p就是从那里获取的。

        【讨论】:

          【解决方案5】:

          制作一些自定义方法并根据您的要求使用它们。下面是一些例子,

          // Create a method to draw Line of any size anywhere in the pdf,
          
          - (void) drawLine:(CGFloat)ofWidth fromPoint:(CGPoint)from toPoint(CGPoint)to withColor:(UIColor *)color {
              //Get Current Graphics Context as a CGContextRef That Provides Graphic Environment for drawing in Quartz 2D
              CGContextRef    currentContext = UIGraphicsGetCurrentContext();
          
              //Sets the width of line we going to draw.
              CGContextSetLineWidth(currentContext, ofWidth);
          
          
              //Sets the strok color of context
              CGContextSetStrokeColorWithColor(currentContext, color.CGColor);
          
              //Starting point of line as X,Y Value
              CGPoint startPoint = from;
          
              //Starting point of line as X,Y Value 
              CGPoint endPoint = to;
          
              //Creates new empty path in given graphic context
              CGContextBeginPath(currentContext);
          
              //Begin a new subpath at given points
              CGContextMoveToPoint(currentContext, startPoint.x, startPoint.y);
          
              //Append line from the current points to the given points as parameter
              CGContextAddLineToPoint(currentContext, endPoint.x, endPoint.y);
          
              //Terminates the subpath of the context
              CGContextClosePath(currentContext);
          
              //Draw the corrunt path using drawing mode as paramete.
              CGContextDrawPath(currentContext, kCGPathFillStroke);
          }  
          

          这是将任何大小、任何颜色和任何字体的文本放在任何地方的方法,

          - (void) drawText:(NSString *)text ofColor:(CGFloat)red Green:(CGFloat)green Blue:(CGFloat)blue withAlpha:(CGFloat)alpha withFont:(UIFont *)font atPoint:(CGRect)Point havingTextAlignment:(UITextAlignment)textAlignment{
              //Get Current Graphics Context as a CGContextRef That Provides Graphic Environment for drawing in Quartz 2D
              CGContextRef    currentContext = UIGraphicsGetCurrentContext();
          
              //Fill the current context with the color.
              CGContextSetRGBFillColor(currentContext,red,green,blue,alpha);
          
          
              //String to Draw
              NSString *textToDraw = text;
          
          
              [textToDraw drawInRect:Point
                            withFont:font
                       lineBreakMode:UILineBreakModeWordWrap
                           alignment:textAlignment];
          }
          

          图片也是如此,

          - (void) drawImage:(UIImage *)image atFrame:(CGRect)frame {
              [image drawInRect:frame];
          }
          

          现在您可以使用这些方法创建任何类型的 pdf,

          - (void) generatePdfWithFilePath: (NSString *)thefilePath ofData:(NSDictionary *)data andPageSize:(CGSize) pageSize{
          
              UIGraphicsBeginPDFContextToFile(thefilePath, CGRectZero, nil);
          
                  // For exampl
              [self drawLine:65.0 fromPoint: CGPointMake( 10, 50) toPoint:CGPointMake(pageSize.width - 100) withColor:[UIColor colorWithRed:239.0/255.0 green:239.0/255.0 blue:239.0/255.0 alpha:1.0]];
          
              [self drawText:@"Testing text" ofColor:0.0 Green:0.0 Blue:0.0 withAlpha:1.0 withFont:[UIFont systemFontOfSize:16.0] atPoint:CGRectMake(60,200, pageSize.width - 200,30.0) havingTextAlignment:UITextAlignmentLeft];
          
              UIGraphicsEndPDFContext();
          }
          

          您还可以通过以下方式获得帮助,

          http://www.raywenderlich.com/6581/how-to-create-a-pdf-with-quartz-2d-in-ios-5-tutorial-part-1
          http://www.raywenderlich.com/6818/how-to-create-a-pdf-with-quartz-2d-in-ios-5-tutorial-part-2

          【讨论】:

            猜你喜欢
            • 2015-08-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-05-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-12-05
            相关资源
            最近更新 更多