有没有办法从iOs中的XML / HTML模板生成PDF文件

时间:2021-03-22 00:26:25

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

我正在创建一个iPad应用程序,因为我必须使用不同的PDF表单。我有一些使用Quartz2D通过代码生成PDF文件的方法。但我必须通过代码编写完整的表单。我将来可能要更新PDF表单,所以我必须再编写代码。所以我听说有一个名为iTextSharp的组件用于.net pdf创建 - iOS有类似的东西吗?这样我就可以使用一些XML模板来创建PDF文件。请帮忙,谢谢

2 个解决方案

#1


14  

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.

我使用iOS打印子系统和UIMarkupTextPrintFormatter在我的应用程序中执行此操作。诀窍是编写自己的自定义UIPrintPageRenderer,它覆盖并返回paperRect和numberOfPages中的正确值。您将UIMarkupTextPrintFormatter添加到自定义UIPrintPageRenderer。

Then, you'll need routines similar to this, in the context of your custom UIPrintPageRenderer:

然后,在自定义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;
}

#2


1  

@TomSwift : agree with his answer but i would like to explain in better way

@TomSwift:同意他的回答,但我想以更好的方式解释

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");
}

#1


14  

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.

我使用iOS打印子系统和UIMarkupTextPrintFormatter在我的应用程序中执行此操作。诀窍是编写自己的自定义UIPrintPageRenderer,它覆盖并返回paperRect和numberOfPages中的正确值。您将UIMarkupTextPrintFormatter添加到自定义UIPrintPageRenderer。

Then, you'll need routines similar to this, in the context of your custom UIPrintPageRenderer:

然后,在自定义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;
}

#2


1  

@TomSwift : agree with his answer but i would like to explain in better way

@TomSwift:同意他的回答,但我想以更好的方式解释

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");
}