2016-06-28 1 views
3

HTML 텍스트에서 pdf를 생성하기 위해 itext-5.3.4.jar 및 xmlworker-1.2.1.jar 라이브러리를 사용하고 있습니다. html에는 이미지 로고와 인라인 CSS가 포함되어 있습니다.HTML 텍스트 문자열에서 pdf를 생성하고 itext를 사용하여 안드로이드 용 CSS를 생성합니다.

내 HTML 파일 및 이미지가 Asset 폴더에 있습니다.이 라이브러리를 사용하면 성공적으로 생성되지만 이미지 표시가없고 CSS 스타일이 없습니다. 누구든지이 문제를 해결하기 위해해야 ​​할 제안이 있습니다. 다른 라이브러리 또는 html에서 pdf 생성을위한 다른 옵션이 도움이 될 경우.

public static void generatePdfFromHtlm(String fileName, String htmlString){ 


    try { 
     File mediaStorageDir = new File(Environment.getExternalStorageDirectory(), AppConfig.getContext().getPackageName() + "/" + "Pdf"); 

     if (!mediaStorageDir.exists()) { 
      mediaStorageDir.mkdirs(); 
     } 

     File fileWithinMyDir = new File(mediaStorageDir, fileName); 

     FontFactory.registerDirectories(); 
     Document document = new Document(PageSize.A4); 
     PdfWriter writer = PdfWriter.getInstance(document, 
       new FileOutputStream(fileWithinMyDir)); 
     document.open(); 
     HtmlPipelineContext htmlContext = new HtmlPipelineContext(null); 
     htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory()); 
     htmlContext.setImageProvider(new AbstractImageProvider() { 
      public String getImageRootPath() { 

       Uri uri = Uri.parse("file:///android_asset/"); 

       String newPath = uri.toString(); 

       return newPath; 
      } 
     }); 


     CSSResolver cssResolver = 
       XMLWorkerHelper.getInstance().getDefaultCssResolver(false); 
     /*Pipeline<?> pipeline = 
       new CssResolverPipeline(cssResolver, 
         new HtmlPipeline(htmlContext, 
           new PdfWriterPipeline(document, writer)));*/ 

     // Pipelines 
     PdfWriterPipeline pdf = new PdfWriterPipeline(document, writer); 
     HtmlPipeline html = new HtmlPipeline(htmlContext, pdf); 
     CssResolverPipeline css = new CssResolverPipeline(cssResolver, html); 

     XMLWorker worker = new XMLWorker(css, true); 

     XMLParser p = new XMLParser(worker); 
     InputStream is = new ByteArrayInputStream(htmlString.getBytes()); 
     p.parse(is); 

     document.close(); 


    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

내 html 파일이

<!DOCTYPE html> 
 
<!--[if IE 8]> <html lang="en" class="ie8"> <![endif]--> 
 
<!--[if IE 9]> <html lang="en" class="ie9"> <![endif]--> 
 
<!--[if !IE]><!--> 
 
<html lang="en"> <!--<![endif]--> 
 

 
<!-- BEGIN HEAD --> 
 
<head> 
 
    <meta charset="utf-8" /> 
 
    
 
    <title>WeighInsheet</title> 
 
    
 
    
 
    <style type="text/css"> 
 
    
 
    body { font-family:Arial; } 
 
     .Wrapper { border:1px solid #cccccc; height:auto; margin:0px 65px;} 
 
     .header { height:105px; margin:5px; float:left;} 
 
     .logo { width:100px; height:100px; float:left; } 
 
    .heading { width:600px;} 
 
    h2{ margin:40px 0px 0px 0px;font-size: 22px; font-weight:bold;} 
 
    h3{ margin:0px; font-weight:normal;font-size: 16px;} 
 
    table { border-collapse: collapse; border-spacing: 0; width:100%; } 
 
    table td { font-family: arial; font-size: 14px; padding: 10px 5px; border: 1px solid #ddd; } 
 
    table th { background-color:#000000; color:#ffffff; font-family: arial; font-size: 16px; font-weight: bold; 
 
      border: 1px solid #ddd; } 
 
    
 
    </style> 
 

 

 
</head> 
 

 
<!-- END HEAD --> 
 

 
<!-- BEGIN BODY --> 
 

 
<body> 
 
    
 
<div class="Wrapper"> 
 

 
<div class="header"> 
 

 
<div class="logo"><img src="logo.jpg" class="logo"/></div> 
 

 
<div class="heading" align="center"> 
 
<h2>Description</h2> 
 
<h3>Title Meta</h3> 
 
</div> 
 

 
</div> 
 
<table> 
 

 
<thead> 
 
##CHANGEHEADER## 
 
</thead> 
 

 
<tbody> 
 
    ##CHANGEBODY## 
 
</tbody> 
 

 
</table> 
 

 
</div> 
 

 
</body> 
 

 
<!-- END BODY --> 
 

 
</html>

내 이미지 파일 "logo.jpg"입니다 : PDF 파일을 생성하기위한

나는이 기능을 사용하고 있습니다 자산 폴더에 있습니다.

+1

왜 안드로이드 포트 iTextG를 사용하지 않습니까? 왜 현재 버전 5.5.9를 사용하지 않으시겠습니까? –

+0

java.lang.NoSuchMethodError : 가상 메서드 없음 addCell (Lcom/itextpdf/text/pdf/PdfPCell;) Lcom/itextpdf/text/pdf/PdfPTable 클래스의 V; 또는 그 수퍼 클래스 ('com.itextpdf.text.pdf.PdfPTable'의 선언은 /data/app/com.test.pdfgenerate-1/base.apk에 나타납니다) –

+0

업데이트 itext 5.5.9 이후에이 오류가 발생합니다 –

답변

2

나는 XML Worker 클래스로 PDF 생성 문제를 수정했습니다.

CSS는 그것을 외부 CSS 파일을 작성하고 적용 작동하지 않는 경우, 전 대한

.

InputStream is = new ByteArrayInputStream(aHtmlString.getBytes()); 
          InputStream css = new ByteArrayInputStream(cssString.getBytes()); 

          XMLWorkerHelper.getInstance().parseXHtml(writer, document, is, css); 

이미지 표시의 경우 이미지를 자산 폴더에서 휴대폰 내부 폴더로 복사합니다.

해당 폴더 이미지 경로에 img 태그를 추가하십시오.

예 : 자산에서 복사 파일이 방법은 폴더하는

<img src="/storage/emulated/0/MyApp/Images/my_logo.jpg"/> 

사용.

public static void listAssetFiles(String path,Context ctx,String folderPath) { 

    String [] list; 
    try { 
     list = ctx.getAssets().list(path); 
     if (list.length > 0) { 
      // This is a folder 
      for (String file : list) { 

       copyIntoFolder(file,ctx,path+"/",folderPath); 
      } 
     } 
    } catch (IOException e) { 

    } 



} 

public static void copyIntoFolder(String fileName, Context ctx, String filePath, String folderPath){ 
    AssetManager assetManager = ctx.getAssets(); 
    InputStream in = null; 
    OutputStream out = null; 
    try { 
     in = assetManager.open(filePath+fileName); 
     File outFile = new File(folderPath , fileName); 
     out = new FileOutputStream(outFile); 
     Utility.copyFile(in, out); 
     in.close(); 
     // in = null; 
     out.flush(); 
     out.close(); 
     //out = null; 
    } catch(IOException e) { 
     Log.e("IOException", "copyIntoFolder: ",e); 

    } 
} 

iText를 나던 지원 아래의 모든 CSS 속성이 지원되는 CSS 속성을 따라 HTML을 생성, suported CSS 속성의 목록입니다.

Css Support

+0

html 파일에서 CSS 부분을 제거 했습니까? 헤더 안쪽에 CSS가있는 html 파일이있어서 그것을 적용 할 수 없습니다 !! –

+0

예 HTML 헤더에서 인라인으로 CSS를 사용했습니다. –

1

iText를 샤프 property.You가 웹보기에서 HTML을로드하고이 코드를 사용하여 PDF를 생성 할 수있는 모든 CSS를 지원하지 않습니다.

private void createWebPrintJob(WebView webView) { 

     try { 
      PrintDocumentAdapter printAdapter; 
      String jobName = getString(R.string.app_name) + " Document"; 
      PrintAttributes attributes = new PrintAttributes.Builder() 
        .setMediaSize(PrintAttributes.MediaSize.ISO_A4) 
        .setResolution(new PrintAttributes.Resolution("pdf", "pdf", 600, 600)) 
        .setMinMargins(PrintAttributes.Margins.NO_MARGINS).build(); 
      File path = new File(Environment.getExternalStorageDirectory() 
        .getAbsolutePath() + "/AamirPDF/"); 


      path.mkdirs(); 
      PdfPrint pdfPrint = new PdfPrint(attributes); 
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
       printAdapter = webView.createPrintDocumentAdapter(jobName); 
      } else { 
       printAdapter = webView.createPrintDocumentAdapter(); 
      } 


      pdfPrint.printNew(printAdapter, path, "output_" + System.currentTimeMillis() + ".pdf", getActivity().getCacheDir().getPath()); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

    } 

PDF 생성을위한 PdfPrint 클래스.

package com.example.nisarg.invoice; 

import android.os.Bundle; 
import android.os.CancellationSignal; 
import android.os.ParcelFileDescriptor; 
import android.print.PageRange; 
import android.print.PrintAttributes; 
import android.print.PrintDocumentAdapter; 
import android.util.Log; 

import com.example.nisarg.invoice.android.print.ProxyBuilder; 

import java.io.File; 
import java.io.IOException; 
import java.lang.reflect.InvocationHandler; 
import java.lang.reflect.Method; 

import static com.example.nisarg.invoice.Database.appglobal.context; 

public class PdfPrint { 

    public static final String TAG = PdfPrint.class.getSimpleName(); 
    public static PrintAttributes printAttributes; 
    File cacheFolder; 


    public PdfPrint(PrintAttributes printAttributes) { 
     this.printAttributes = printAttributes; 
     cacheFolder = new File(context.getFilesDir() + "/etemp/"); 
    } 

    public static PrintDocumentAdapter.WriteResultCallback getWriteResultCallback(InvocationHandler invocationHandler, 
                        File dexCacheDir) throws IOException { 
     return ProxyBuilder.forClass(PrintDocumentAdapter.WriteResultCallback.class) 
       .dexCache(dexCacheDir) 
       .handler(invocationHandler) 
       .build(); 
    } 

    public static PrintDocumentAdapter.LayoutResultCallback getLayoutResultCallback(InvocationHandler invocationHandler, 
                        File dexCacheDir) throws IOException { 
     return ProxyBuilder.forClass(PrintDocumentAdapter.LayoutResultCallback.class) 
       .dexCache(dexCacheDir) 
       .handler(invocationHandler) 
       .build(); 
    } 

    /* public void print(final PrintDocumentAdapter printAdapter, final File path, final String fileName) { 
     printAdapter.onLayout(null, printAttributes, null, new PrintDocumentAdapter.LayoutResultCallback() { 
      @Override 
      public void onLayoutFinished(PrintDocumentInfo info, boolean changed) { 


       try { 
        PrintDocumentAdapter.WriteResultCallback callback = getWriteResultCallback(new InvocationHandler() { 
         @Override 
         public Object invoke(Object o, Method method, Object[] objects) throws Throwable { 
          if (method.getName().equals("onWriteFinished")) { 
           //       pdfCallback.onPdfCreated(); 
          } else { 
           Log.e(TAG, "Layout failed"); 
           //       pdfCallback.onPdfFailed(); 
          } 
          return null; 
         } 
        }, null); 

        printAdapter.onWrite(new PageRange[]{PageRange.ALL_PAGES}, getOutputFile(path, fileName), new CancellationSignal(), callback); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 


      } 
     }, null); 
    }*/ 

    public void printNew(final PrintDocumentAdapter printAdapter, final File path, final String fileName, final String fileNamenew) { 

     try { 

      printAdapter.onStart(); 
      printAdapter.onLayout(null, printAttributes, new CancellationSignal(), getLayoutResultCallback(new InvocationHandler() { 
       @Override 
       public Object invoke(Object o, Method method, Object[] objects) throws Throwable { 

        if (method.getName().equals("onLayoutFinished")) { 
         onLayoutSuccess(printAdapter, path, fileName, fileNamenew); 
        } else { 
         Log.e(TAG, "Layout failed"); 

        } 
        return null; 
       } 
      }, new File(fileNamenew)), new Bundle()); 


     } catch (Exception e) { 
      e.printStackTrace(); 

     } 
    } 

    private void onLayoutSuccess(PrintDocumentAdapter printAdapter, File path, String fileName, String filenamenew) throws IOException { 
     PrintDocumentAdapter.WriteResultCallback callback = getWriteResultCallback(new InvocationHandler() { 
      @Override 
      public Object invoke(Object o, Method method, Object[] objects) throws Throwable { 
       if (method.getName().equals("onWriteFinished")) { 

        System.out.print("hello"); 

       } else { 
        Log.e(TAG, "Layout failed"); 

       } 
       return null; 
      } 
     }, new File(filenamenew)); 
     printAdapter.onWrite(new PageRange[]{PageRange.ALL_PAGES}, getOutputFile(path, fileName), new CancellationSignal(), callback); 
    } 

    private ParcelFileDescriptor getOutputFile(File path, String fileName) { 
     if (!path.exists()) { 
      path.mkdirs(); 
     } 
     File file = new File(path, fileName); 
     try { 
      file.createNewFile(); 
      return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_WRITE); 
     } catch (Exception e) { 
      Log.e(TAG, "Failed to open ParcelFileDescriptor", e); 
     } 
     return null; 
    } 
} 

클래스의 프록시를 생성합니다. [ https://gist.github.com/brettwold/838c092329c486b6112c8ebe94c8007e] 프록시 빌더 클래스에서 사용되는 의존성

가 Gradle을이 줄을 추가합니다.

compile 'com.linkedin.dexmaker:dexmaker-mockito:2.2.0' 
관련 문제