iText – HTML to PDF - Image is not displayed in PDF

不打扰是莪最后的温柔 提交于 2019-11-30 08:15:18

I think you can do it easily using a Servlet for viewing the image. How to write a servlet for this is here

Here a sample dispatcher for you. Just edit the required places as needed

@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);
        }
    }
}




}
sanjiv ranjan

Here are some examples: https://developers.itextpdf.com/examples/xml-worker-itext5/html-images

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

If the HTML file you're parsing is stored in a directory that is different from the working directory, iText won't be able to create Image objects. We have to supply an implementation of the ImageProvider interface that tells iText what to do if an img tag is encountered. This interface has the following methods:

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

You can write your own class implementing these four methods, or you can subclass AbstractImageProvider. It is preferred to do the latter. XML Worker will use the store() method of the AbstractImageProvider class to cache all the Image objects that are encountered in a Map. These objects will be reused when the retrieve() method is called for an image with the same src. If you don't cache images, your PDF will be bloated. The same image bits and bytes will be written to the PDF more than once. The reset() method clears the cache; it is used when an ImageProvider is cloned. Finally, the getImageRootPath() method isn't implemented.

If the HTML file you're parsing is stored in a directory that is different from the working directory, iText won't be able to create Image objects. We have to supply an implementation of the ImageProvider interface that tells iText what to do if an img tag is encountered. This interface has the following methods:

You can write your own class implementing these four methods, or you can subclass AbstractImageProvider. It is preferred to do the latter. XML Worker will use the store() method of the AbstractImageProvider class to cache all the Image objects that are encountered in a Map. These objects will be reused when the retrieve() method is called for an image with the same src. If you don't cache images, your PDF will be bloated. The same image bits and bytes will be written to the PDF more than once. The reset() method clears the cache; it is used when an ImageProvider is cloned. Finally, the getImageRootPath() method isn't implemented. You have to implement it yourself, as is done in the following snippet:

to show image with Itext, you have to Changing the default configuration about Image Provider Like it : i do it from 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.");        
    }}

Try getting the image into a memory or byte stream object and then cast that image object to an itextsharp image one.

explore the overloads of iTextSharp.text.Image

EDIT:

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

Get image from your local drive as:

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

Note:: If you have the image on your application folder then we have functions to get the local file path of them in C#. Don't know about Java. Images from external site can be downloaded as

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

Now convert this byte stream to an image object as

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

Now acreate an iTextSharp image object from it and add it to your doucment as

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

Hope this helps you.

I also faced to same issue..

but it was working with the image absolute path. it seems not working with remote path. What id did here is save the image in temp location of file system and generates pdf , finally delete the image file from temp location.

<img src="/home/jboss/temp/imgs/img.png"/>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!