2015-10-15 75 views
0

我测试了this comment中的代码,因为引发了异常,所以无法添加链接。如何使用iText和XmlWorker在PDFA/1B上包含链接(HTML为PDF/A)

为了重现问题,只添加一个html链接。只有添加了此行Main.java

buf.append("<a href='http://google.com'>link to google</a>"); 

的style.css

* { 
    font-family: "Arial"; 
    font-style: normal; 
} 

Main.java

package com.itextpdf; 

import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.OutputStream; 
import java.io.Reader; 
import java.io.StringReader; 

import com.itextpdf.text.Document; 
import com.itextpdf.text.pdf.ICC_Profile; 
import com.itextpdf.text.pdf.PdfAConformanceLevel; 
import com.itextpdf.text.pdf.PdfAWriter; 
import com.itextpdf.tool.xml.XMLWorker; 
import com.itextpdf.tool.xml.XMLWorkerHelper; 
import com.itextpdf.tool.xml.css.CssFile; 
import com.itextpdf.tool.xml.css.StyleAttrCSSResolver; 
import com.itextpdf.tool.xml.html.CssAppliers; 
import com.itextpdf.tool.xml.html.CssAppliersImpl; 
import com.itextpdf.tool.xml.html.Tags; 
import com.itextpdf.tool.xml.parser.XMLParser; 
import com.itextpdf.tool.xml.pipeline.css.CSSResolver; 
import com.itextpdf.tool.xml.pipeline.css.CssResolverPipeline; 
import com.itextpdf.tool.xml.pipeline.end.PdfWriterPipeline; 
import com.itextpdf.tool.xml.pipeline.html.HtmlPipeline; 
import com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext; 

public class Main { 

    public static void main(String[] args) { 

     StringBuffer buf = new StringBuffer(); 

     String title = "Test"; 

     // Sample HTML content. 
     buf.append("<!DOCTYPE html>"); 
     buf.append("<html>"); 
     buf.append("<head>"); 
     buf.append("<title>" + title + "</title>"); 
     buf.append("</head>"); 
     buf.append("<body>"); 
     buf.append("<p>This is a test</p>"); 
     buf.append("<a href='http://google.com'>link to google</a>"); //<----- Only added this line 
     buf.append("</body>"); 
     buf.append("</html>"); 

     OutputStream file = null; 
     Document document = null; 
     PdfAWriter writer = null; 

     try { 

      file = new FileOutputStream(new File("C:\\Users\\amartin\\Desktop\\Test.pdf")); 
      document = new Document(); 
      writer = PdfAWriter.getInstance(document, file, PdfAConformanceLevel.PDF_A_1B); 

      // Avoid discrepances between document title and XMP metadata information. 
      document.addTitle(title); 

      // Create XMP metadata. It's a PDF/A requirement. 
      writer.createXmpMetadata(); 

      document.open(); 

      // Set output intent. PDF/A requirement. 
      ICC_Profile icc = ICC_Profile.getInstance(new FileInputStream("./src/main/resources/com/itextpdf/sRGB Color Space Profile.icm")); 
      writer.setOutputIntents("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", icc); 

      // CSS stylesheet. 
      CSSResolver cssResolver = new StyleAttrCSSResolver(); 
      CssFile cssFile = XMLWorkerHelper.getCSS(new FileInputStream("./css/style.css")); 
      cssResolver.addCss(cssFile); 

      MyFontProvider fontProvider = new MyFontProvider(); 
      fontProvider.register("./fonts/arial.ttf"); 

      /* DEBUG 
      System.out.println("Fonts present in " + fontProvider.getClass().getName()); 
      Set<String> registeredFonts = fontProvider.getRegisteredFonts(); 
      for (String font : registeredFonts) 
       System.out.println(font); 
      */ 

      CssAppliers cssAppliers = new CssAppliersImpl(fontProvider); 
      HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers); 
      htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory()); 

      // 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); 

      Reader reader = new StringReader(buf.toString()); 
      p.parse(reader); 

     } catch (Exception e) { 

      e.printStackTrace(); 

     } finally { 

      if (document != null && document.isOpen()) 
       document.close(); 

      try { 

       if (file != null) 
        file.close(); 

      } catch (IOException e) {} 

      if (writer != null && !writer.isCloseStream()) 
       writer.close(); 

     } 

    } 

} 

MyFontProvider.java

package com.itextpdf; 

import com.itextpdf.text.BaseColor; 
import com.itextpdf.text.Font; 
import com.itextpdf.text.FontFactoryImp; 

public class MyFontProvider extends FontFactoryImp { 

    @Override 
    public Font getFont(String fontname, String encoding, boolean embedded, 
      float size, int style, BaseColor color) { 

     System.out.println("=fontname: " + fontname + " =encoding: " + encoding + " =embedded : " + embedded + " =size: " + size + " =style: " + style + " =BaseColor: " + color); 

     return super.getFont(fontname, encoding, embedded, size, style, color); 

    } 

} 

异常

Exception in thread "main" com.itextpdf.text.pdf.PdfAConformanceException: An annotation dictionary shall contain the F key. 
    at com.itextpdf.text.pdf.internal.PdfA1Checker.checkAnnotation(PdfA1Checker.java:422) 
    at com.itextpdf.text.pdf.internal.PdfAChecker.checkPdfAConformance(PdfAChecker.java:219) 
    at com.itextpdf.text.pdf.internal.PdfAConformanceImp.checkPdfIsoConformance(PdfAConformanceImp.java:71) 
    at com.itextpdf.text.pdf.PdfWriter.checkPdfIsoConformance(PdfWriter.java:3426) 
    at com.itextpdf.text.pdf.PdfWriter.checkPdfIsoConformance(PdfWriter.java:3422) 
    at com.itextpdf.text.pdf.PdfAnnotation.toPdf(PdfAnnotation.java:999) 
    at com.itextpdf.text.pdf.PdfIndirectObject.writeTo(PdfIndirectObject.java:158) 
    at com.itextpdf.text.pdf.PdfWriter$PdfBody.write(PdfWriter.java:420) 
    at com.itextpdf.text.pdf.PdfWriter$PdfBody.add(PdfWriter.java:398) 
    at com.itextpdf.text.pdf.PdfWriter$PdfBody.add(PdfWriter.java:373) 
    at com.itextpdf.text.pdf.PdfWriter$PdfBody.add(PdfWriter.java:369) 
    at com.itextpdf.text.pdf.PdfWriter.addToBody(PdfWriter.java:843) 
    at com.itextpdf.text.pdf.internal.PdfAnnotationsImp.rotateAnnotations(PdfAnnotationsImp.java:209) 
    at com.itextpdf.text.pdf.PdfDocument.newPage(PdfDocument.java:990) 
    at com.itextpdf.text.pdf.PdfDocument.close(PdfDocument.java:865) 
    at com.itextpdf.text.Document.close(Document.java:416) 
    at com.itextpdf.Main.main(Main.java:113) 
+0

没有我们解决这个问题的iText的5.5.7,当我们做了这种变化:https://github.com/ itext/pdfa/commit/ae68c207a25917627f2eca669a3bff0281569b23您正在使用哪个版本的iText和XML Worker? –

+0

两者都是5.5.2版本。 将链接文本设置为span或粗体,正确生成pdf 'buf.append(“This is a link”);' – jagr

+1

在这种情况下,请检查问题是否仍然存在于5.5.7中。您可能遇到了已经解决的问题(我想我以前看过这个问题,并且它已经修复)。 –

回答

3

如何来解决这个问题:

  • 正如布鲁诺说,更新到5.5.7版本的问题就解决了。
  • 如果无法更新库,尝试将文本链接设成<span></span>
相关问题