首页 文章

iText - HTML到PDF - 图像不以PDF格式显示

提问于
浏览
17

我有一个带有文本,图像的html页面,我正在将HTML内容解析为iText以生成PDF . 在生成的PDF中,未显示包含的图像,仅显示文本 .

如果我传递绝对路径,如 D:/Deiva/CRs/HTMLPage/article-101-horz.jpg ,那么图像将被打印 . 但是如果我尝试从服务器上打印图像就像

http://localhost:8085/content/dam/article-101-h1.jpg or http://www.google.co.in/intl/en_ALL/images/logos/images_logo_lg.gif

然后它不会在PDF中打印出来 .

NOTE: 我正在使用 itextpdf-5.2.1.jar 生成PDF .

My HTML Code (Article.html):

<html>
   <head>
   </head>
   <body>   
     <p>Generate PDF with image using iText.</p>
     <img src="http://localhost:8085/content/dam/article-10-h1.jpg"></img>
     <img src="http://www.google.co.in/intl/en_ALL/images/logos/imgs_logo_lg.gif"></img>
     <img class="right horz" src="D:/Deiva/CRs/HTMLPage/article-101-horz.jpg"></img>
   </body>
</html>

I am using the below java code for generating the PDF:

private void createPDF (){

  String path = "D:/Deiva/Test.pdf";
  PdfWriter pdfWriter = null;

  //create a new document
  Document document = new Document();

  try {

   //get Instance of the PDFWriter
   pdfWriter = PdfWriter.getInstance(document, new FileOutputStream(path));

   //document header attributes
   document.addAuthor("betterThanZero");
   document.addCreationDate();
   document.addProducer();
   document.addCreator("MySampleCode.com");
   document.addTitle("Demo for iText XMLWorker");
   document.setPageSize(PageSize.LETTER);

   //open document
   document.open();
   InputStream is = new             FileInputStream("D:/Deiva/CRs/Oncology/Phase5/CR1/HTMLPage/Article.html");

   // create new input stream reader
   InputStreamReader isr = new InputStreamReader(is);

   //get the XMLWorkerHelper Instance
   XMLWorkerHelper worker = XMLWorkerHelper.getInstance();
   //convert to PDF
   worker.parseXHtml(pdfWriter, document, isr);

   //close the document
   document.close();
   //close the writer
   pdfWriter.close();

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

 }

请建议一个以PDF格式显示图像的解决方案 .

提前致谢 .

德瓦玛丽娜

5 回答

  • 3

    我也面临同样的问题..

    但它正在使用图像绝对路径 . 它似乎无法使用远程路径 . 这里的id是将图像保存在文件系统的临时位置并生成pdf,最后从临时位置删除图像文件 .

    <img src="/home/jboss/temp/imgs/img.png"/>
    
  • 1

    尝试将图像放入内存或字节流对象,然后将该图像对象转换为itextsharp图像 .

    探索 iTextSharp.text.Image 的重载

    EDIT:

    Although the code is in C#, it might help you.

    从本地驱动器获取图像:

    Bitmap image1;
    image1 = new Bitmap(@"C:\Documents and Settings\All Users\" 
                + @"Documents\My Music\music.jpeg", true);
    

    Note: :如果你的应用程序文件夹中有图像,那么我们就有了在C#中获取它们的本地文件路径的函数 . 不了解Java . 外部网站的图片可以下载为

    System.Net.WebClient client = new WebClient();
    client.DownloadFile(imageURL, localPathname);   // look into java to get local path
    

    现在将此字节流转换为图像对象

    MemoryStream imgMemoryStream = new MemoryStream(imgByteArray);
    Image myImage = Drawing.Image.FromStream(imgMemoryStream);
    

    现在从中创建一个iTextSharp图像对象并将其添加到您的doucment中

    iTextSharp.text.Image pic = iTextSharp.text.Image.GetInstance(myImage, System.Drawing.Imaging.ImageFormat.Jpeg);
    document.Add(pic);
    

    希望这对你有所帮助 .

  • 4

    以下是一些示例:https://developers.itextpdf.com/examples/xml-worker-itext5/html-images

    htmlContext.setImageProvider(new AbstractImageProvider() {
        public String getImageRootPath() { return "src/main/resources/html/"; }
    });
    

    如果要解析的HTML文件存储在与工作目录不同的目录中,则iText将无法创建Image对象 . 我们必须提供ImageProvider接口的实现,该接口告诉iText如果遇到img标记该怎么做 . 该接口具有以下方法:

    Image retrieve(final String src);
    String getImageRootPath();
    void store(String src, Image img);
    void reset();
    

    您可以编写自己的类来实现这四种方法,也可以创建AbstractImageProvider的子类 . 优选做后者 . XML Worker将使用AbstractImageProvider类的store()方法来缓存Map中遇到的所有Image对象 . 当为具有相同src的图像调用retrieve()方法时,将重用这些对象 . 如果不缓存图像,PDF将会膨胀 . 相同的图像位和字节将不止一次写入PDF . reset()方法清除缓存;克隆ImageProvider时使用它 . 最后,没有实现getImageRootPath()方法 .

    如果要解析的HTML文件存储在与工作目录不同的目录中,则iText将无法创建Image对象 . 我们必须提供ImageProvider接口的实现,该接口告诉iText如果遇到img标记该怎么做 . 该接口具有以下方法:

    您可以编写自己的类来实现这四种方法,也可以创建AbstractImageProvider的子类 . 优选做后者 . XML Worker将使用AbstractImageProvider类的store()方法来缓存Map中遇到的所有Image对象 . 当为具有相同src的图像调用retrieve()方法时,将重用这些对象 . 如果不缓存图像,PDF将会膨胀 . 相同的图像位和字节将不止一次写入PDF . reset()方法清除缓存;克隆ImageProvider时使用它 . 最后,没有实现getImageRootPath()方法 . 您必须自己实现它,如下面的代码片段所示:

  • 0

    要使用Itext显示图像,您必须更改有关Image Provider的默认配置,如下所示:我是从http://demo.itextsupport.com/xmlworker/itextdoc/flatsite.html开始的

    public class HtmlToPDF1 {
      public static void main(String ... args ) throws DocumentException, IOException {    
    
          FontFactory.registerDirectories();
          Document document = new Document();
          PdfWriter writer = PdfWriter.getInstance(document,
              new FileOutputStream("src/test/ressources/mypdf.pdf"));
          document.open(); HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
          htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
          htmlContext.setImageProvider(new AbstractImageProvider() {
              public String getImageRootPath() {
                  return "/home/fallphenix/workspace/JAVA/JEE/testHTMLtoPDF/src/test/ressources/";
              }
          }); CSSResolver cssResolver =
                XMLWorkerHelper.getInstance().getDefaultCssResolver(true);
            Pipeline<?> pipeline =
                new CssResolverPipeline(cssResolver,
                        new HtmlPipeline(htmlContext,
                            new PdfWriterPipeline(document, writer)));
            XMLWorker worker = new XMLWorker(pipeline, true);
            XMLParser p = new XMLParser(worker);
            p.parse(new FileInputStream("src/test/ressources/other.html"));
            document.close();
              System.out.println("Done.");        
        }}
    
  • 3

    我认为你可以使用Servlet轻松地查看图像 . 如何为此编写servlet是here

    这里有一个样本调度员 . 只需根据需要编辑所需的位置

    @Controller
    public class ImageController extends DispatcherServlet {
    
    
    
        private static final int DEFAULT_BUFFER_SIZE = 10240; // 10KB.
    
        // Properties ---------------------------------------------------------------------------------
    
        private String imagePath;
    
       @RequestMapping(value="images/{imageId:.+}", method = RequestMethod.GET)
       public @ResponseBody void getImage(@PathVariable String imageId,HttpServletRequest request, HttpServletResponse response){
            String requestedImage = request.getPathInfo();
             this.imagePath ="image path in server here";
    
             if (requestedImage == null) {
                 // Do your thing if the image is not supplied to the request URI.
                 // Throw an exception, or send 404, or show default/warning image, or just ignore it.
                 try {
                    response.sendError(HttpServletResponse.SC_NOT_FOUND);
                 }catch(IOException ioException){
                    logger.error("error image path incorrect:{}", ioException);
    
                } // 404.
                 return;
             }
    
             File image=null;
            try {
                image = new File(imagePath, URLDecoder.decode(imageId, "UTF-8"));
            } catch (UnsupportedEncodingException unsupportedEncodingException) {
                logger.error("error image can not decode:{}", unsupportedEncodingException);
    
            }
    
             // Check if file actually exists in filesystem.
             if (!image.exists()) {
                 // Do your thing if the file appears to be non-existing.
                 // Throw an exception, or send 404, or show default/warning image, or just ignore it.
                 try {
                    response.sendError(HttpServletResponse.SC_NOT_FOUND);
                 }catch(IOException ioException){
                    logger.error("error image does not exists:{}", ioException);
    
                } // 404.
                 return;
             }
    
             // Get content type by filename.
             String contentType = "jpeg";
             contentType="image/"+contentType;
    
             // Init servlet response.
             response.reset();
             response.setBufferSize(DEFAULT_BUFFER_SIZE);
             response.setContentType(contentType);
             response.setHeader("Content-Length", String.valueOf(image.length()));
             response.setHeader("Content-Disposition", "inline; filename=\"" + image.getName() + "\"");
    
             // Prepare streams.
             BufferedInputStream input = null;
             BufferedOutputStream output = null;
    
             try {
                 // Open streams.
                 try {
                    input = new BufferedInputStream(new FileInputStream(image), DEFAULT_BUFFER_SIZE);
                } catch (FileNotFoundException e) {
    
                    logger.error("error creating file input stream to the image file :{}", e);
    
    
                }
                 try {
    
                     output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);
    
                } catch (IOException e) {
    
    
                    logger.error("error creating output stream to the http response :{}", e);
    
                }
    
                 // Write file contents to response.
                 byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
                 int length;
                 try {
                    while ((length = input.read(buffer)) > 0) {
                         output.write(buffer, 0, length);
                     }
                } catch (IOException e) {
    
                    logger.error("error writing the image file to outputstream :{}", e);
    
                }
             } finally {
                 // Gently close streams.
                 close(output);
                 close(input);
             }
         }
    
         // Helpers (can be refactored to public utility class) ----------------------------------------
    
    
    
    
    private  void close(Closeable resource) {
        if (resource != null) {
            try {
                resource.close();
            } catch (IOException e) {
                // Do your thing with the exception. Print it, log it or mail it.
                logger.error("error closing resources:{}", e);
            }
        }
    }
    
    
    
    
    }
    

相关问题