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

Posted

技术标签:

【中文标题】有没有办法从 iOs 中的 XML/HTML 模板生成 PDF 文件【英文标题】:Is there any way to generate PDF file from a XML/HTML template in iOs 【发布时间】:2012-03-20 16:22:44 【问题描述】:

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

【问题讨论】:

【参考方案1】:

我在我的应用程序中使用 iOS 打印子系统和 UIMarkupTextPrintFormatter 执行此操作。诀窍是编写您自己的自定义 UIPrintPageRenderer,它覆盖并从 paperRect 和 numberOfPages 返回正确的值。您将 UIMarkupTextPrintFormatter(s) 添加到您的自定义 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;

【讨论】:

您是从 XML 模板生成 PDF 文件吗? 谢谢你,你救了我的命!顺便问一下,这个方法app store允许吗? @ChenXin;我有一个使用这种技术批准的应用程序。 哇,非常感谢!这是创建 PDF 文件的好方法,比使用核心图形更好、更容易。 @TomSwift 您是否也设法使用这种技术渲染图像?我尝试了几个选项(自定义 NSURLProtocol、本地文件 URL、base64 图像嵌入),但似乎没有任何效果......对此有什么帮助吗?【参考方案2】:

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

为了能够从UIWebView 创建PDF,需要将 html 加载到 yourWebView,否则可能会隐藏 yourWebView 以生成 PDF,但过程保持不变

1) 添加UIPrintPageRendererCategory 用于获取PDF 数据,因为需要使用yourWebView.viewPrintFormatter

@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) 为 A4 尺寸或您想要的任何自定义尺寸添加这些定义

#define kPaperSizeA4 CGSizeMake(595.2,841.8)

3) 处理我们如何创建 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");

【讨论】:

我正在使用相同的技术。但是如果我设置左右填充> 0,那么 HTML 中的图像将从右侧剪切。有什么建议……??? @san :上面的话对我来说意义重大,而不是赞成。不客气 @PareshNavadiya 我使用了这个方法。一切都很好。但是文本文本在页面之间被破坏了。有什么办法可以解决它。

以上是关于有没有办法从 iOs 中的 XML/HTML 模板生成 PDF 文件的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法从 iOS 中的 QuickBlox 获取更新的徽章计数器?

有没有办法使用 worklight 6.2 或 phonegap 混合应用程序从 android 和 ios 中的另一个应用程序启动一个应用程序?

Django——有没有办法从模板中引用/获取当前页面 URL? [复制]

有没有办法将变量传递给 Django 中的“扩展”模板?

有没有办法覆盖模板中的表单值?

有没有办法在 django 模板中迭代列表中的列表?