iOS使用动态内容创建PDF

时间:2015-01-08 10:40:42

标签: ios objective-c iphone pdf-generation

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

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

5 个答案:

答案 0 :(得分:2)

您可以使用类似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

答案 1 :(得分:2)

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

创建一个块: - 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);

答案 2 :(得分: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 :(得分:0)

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

// 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

答案 4 :(得分:0)

我知道这是一个老问题,但是现在您将使用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,上面是以下摘录的片段。