iphone - 使用 Cocoa-Touch 在 iOS 中将 html 文件转换为 PDF 文档

标签 iphone objective-c cocoa-touch pdf quartz-graphics

我想将 iPhone 上的本地 html 文件转换为 PDF 文档。我使用在网上找到的以下代码从图片生成 PDF 文件,我尝试用 html 文件替换图像但失败了。非常感谢您的帮助。 提前致谢,

// Our method to create a PDF file natively on the iPhone
// This method takes two parameters, a CGRect for size and
// a const char, which will be the name of our pdf file
void CreatePDFFile (CGRect pageRect, const char *filename) {

    // This code block sets up our PDF Context so that we can draw to it
    CGContextRef pdfContext;
    CFStringRef path;
    CFURLRef url;
    CFMutableDictionaryRef myDictionary = NULL;
    // Create a CFString from the filename we provide to this method when we call it
    path = CFStringCreateWithCString (NULL, filename,
                                      kCFStringEncodingUTF8);
    // Create a CFURL using the CFString we just defined
    url = CFURLCreateWithFileSystemPath (NULL, path,
                                         kCFURLPOSIXPathStyle, 0);
    CFRelease (path);
    // This dictionary contains extra options mostly for 'signing' the PDF
    myDictionary = CFDictionaryCreateMutable(NULL, 0,
                                             &kCFTypeDictionaryKeyCallBacks,
                                             &kCFTypeDictionaryValueCallBacks);
    CFDictionarySetValue(myDictionary, kCGPDFContextTitle, CFSTR("My PDF File"));
    CFDictionarySetValue(myDictionary, kCGPDFContextCreator, CFSTR("My Name"));
    // Create our PDF Context with the CFURL, the CGRect we provide, and the above defined dictionary
    pdfContext = CGPDFContextCreateWithURL (url, &pageRect, myDictionary);
    // Cleanup our mess
    CFRelease(myDictionary);
    CFRelease(url);
    // Done creating our PDF Context, now it's time to draw to it

    // Starts our first page
    CGContextBeginPage (pdfContext, &pageRect);

    // Draws a black rectangle around the page inset by 50 on all sides
    CGContextStrokeRect(pdfContext, CGRectMake(50, 50, pageRect.size.width - 100, pageRect.size.height - 100));

    // This code block will create an image that we then draw to the page
    const char *picture = "Picture";
    CGImageRef image;
    CGDataProviderRef provider;
    CFStringRef picturePath;
    CFURLRef pictureURL;

    picturePath = CFStringCreateWithCString (NULL, picture,
                                      kCFStringEncodingUTF8);
    pictureURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), picturePath, CFSTR("png"), NULL);
    CFRelease(picturePath);
    provider = CGDataProviderCreateWithURL (pictureURL);
    CFRelease (pictureURL);
    image = CGImageCreateWithPNGDataProvider (provider, NULL, true, kCGRenderingIntentDefault);
    CGDataProviderRelease (provider);
    CGContextDrawImage (pdfContext, CGRectMake(200, 200, 207, 385),image);
    CGImageRelease (image);


    // End image code

    // Adding some text on top of the image we just added
    CGContextSelectFont (pdfContext, "Helvetica", 16, kCGEncodingMacRoman);
    CGContextSetTextDrawingMode (pdfContext, kCGTextFill);
    CGContextSetRGBFillColor (pdfContext, 0, 0, 0, 1);
    const char *text = "Hello World!";
    CGContextShowTextAtPoint (pdfContext, 260, 390, text, strlen(text));
    // End text

    // We are done drawing to this page, let's end it
    // We could add as many pages as we wanted using CGContextBeginPage/CGContextEndPage
    CGContextEndPage (pdfContext);

    // We are done with our context now, so we release it
    CGContextRelease (pdfContext);
}

- (IBAction)createPDF:(id)sender {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *saveDirectory = [paths objectAtIndex:0];
    NSString *saveFileName = @"myPDF.pdf";
    NSString *newFilePath = [saveDirectory stringByAppendingPathComponent:saveFileName];
    const char *filename = [newFilePath UTF8String];
    CreatePDFFile(CGRectMake(0, 0, 612, 792),filename);
}

最佳答案

我根据周围发现的每条好建议创建了一个类(class)。我一直在深入挖掘,我希望我的类(class)能为任何尝试直接从某些 HTML 源创建多页 PDF 的人提供一些良好的开端。

你会在这里找到完整的代码和一些基本的示例代码:https://github.com/iclems/iOS-htmltopdf

我遇到了和你一样的问题,我的要求是: - 完整的 PDF(真实文本,无位图) - 智能多页(与每隔 X 像素切割一个全高 webview 相比...)

因此,我使用的解决方案非常好,因为它采用了 iOS 用于拆分页面以进行打印的相同工具。

让我解释一下,我设置了一个基于 web View 打印格式化程序的 UIPrintPageRenderer(第一个提示):

UIPrintPageRenderer *render = [[UIPrintPageRenderer alloc] init];

[render addPrintFormatter:webView.viewPrintFormatter startingAtPageAtIndex:0];

CGRect printableRect = CGRectMake(self.pageMargins.left,
                              self.pageMargins.top,
                              self.pageSize.width - self.pageMargins.left - self.pageMargins.right,
                              self.pageSize.height - self.pageMargins.top - self.pageMargins.bottom);

CGRect paperRect = CGRectMake(0, 0, self.pageSize.width, self.pageSize.height);

[render setValue:[NSValue valueWithCGRect:paperRect] forKey:@"paperRect"];
[render setValue:[NSValue valueWithCGRect:printableRect] forKey:@"printableRect"];

NSData *pdfData = [render printToPDF];

[pdfData writeToFile: self.PDFpath  atomically: YES];

同时,我在 UIPrintPageRenderer 上创建了一个类别来支持:

-(NSData*) printToPDF
{
    [self doNotRasterizeSubviews:self.view];

    NSMutableData *pdfData = [NSMutableData data];

    UIGraphicsBeginPDFContextToData( pdfData, CGRectZero, 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;
}

关于iphone - 使用 Cocoa-Touch 在 iOS 中将 html 文件转换为 PDF 文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6316192/

相关文章:

c++ - 在 iPhone 项目中链接 C++ 源代码

ios - 将当前时间更改为印度标准时间

iphone - xcode ios objective-c mkmapview : compare MKMapView span

iPhone:获取音频文件的持续时间

iphone - 音频广播

iphone - 如何处理用户数据在不同时间到达的多个推送通知?

ios - 当我在 xcode 中构建我的应用程序时,出现错误 :/bin/sh: bad interpreter: Operation not permitted

ios - didMoveToSuperview 没有被调用

ios - 从 iOS 9 开始,应用程序 :openURL:sourceApplication:annotation: is deprecated, 如何在 iOS 8 中使用新方法?

ios - 填充时从 Collection View 中选择一个单元格