在iOS中是否有一种方法可以从XML/HTML模板生成PDF文件?

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

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

谢谢,你救了我的命!顺便问一下,这种方法被应用商店允许吗? - ChenXin
@ChenXin;我已经使用这种技术成功地通过了一个应用程序的审核。 - TomSwift
3
@TomSwift,您是否能够使用这种技术来渲染图像?我尝试了几个选项(自定义NSURLProtocol、本地文件URL、Base64图像嵌入),但似乎都不起作用……对此有任何帮助吗? - nicolasthenoz
有人能给我完整的代码将HTML转换为PDF吗?我非常需要它。 - Raj
嗨,我有一个需求,需要加载一个HTML文件,该文件将包含文本字段、标签、复选框按钮等。我需要获取用户输入的数据,然后将其转换为带有用户输入数据的PDF文件。 - amit soni
显示剩余9条评论

1

@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中的图像将从右侧裁剪。有什么建议吗....??? - M Zubair Shamshad
@san:上面的话对我来说意义非凡,比起赞同,更加让我感激。不客气。 - Paresh Navadiya
@PareshNavadiya 我使用了这种方法。一切都很好。但是文本在页面之间断开了。有没有办法修复它? - UIBittu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接