使用iText将HTML转换为PDF:如何生成复选框

5

我有一个简单的HTML页面,iText可以从中生成PDF。这很好,但是复选框被忽略了。我该怎么办?

import java.io.FileOutputStream;
import java.io.StringReader;

import com.itextpdf.text.Document;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.html.simpleparser.HTMLWorker;
import com.itextpdf.text.pdf.PdfWriter;

public class HtmlToPDF {

  public static void main(String ... args ) {
    try {
      Document document = new Document(PageSize.LETTER);
      PdfWriter pdfWriter = PdfWriter.getInstance(document, new FileOutputStream("c://temp//testpdf.pdf"));
      document.open();
      String str = "<HTML><HEAD></HEAD><BODY><H1>Testing</H1><FORM>" + 
                   "check : <INPUT TYPE='checkbox' CHECKED/><br/>" +
                   "</FORM></BODY></HTML>";

      htmlWorker.parse(new StringReader(str));
      document.close();
      System.out.println("Done.");
      } 
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

我用YAHP(http://www.allcolor.org/YaHPConverter/)使它工作了。

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


// http://www.allcolor.org/YaHPConverter/
import org.allcolor.yahp.converter.CYaHPConverter;
import org.allcolor.yahp.converter.IHtmlToPdfTransformer;

public class HtmlToPdf_yahp {

    public  static void main(String ... args ) throws Exception {
        htmlToPdfFile();
    }

    public static void htmlToPdfFile() throws Exception {
            CYaHPConverter converter = new CYaHPConverter();
            File fout = new File("c:/temp/x.pdf");
            FileOutputStream out = new FileOutputStream(fout);
            Map properties = new HashMap();
            List headerFooterList = new ArrayList();

            String str = "<HTML><HEAD></HEAD><BODY><H1>Testing</H1><FORM>" +
                         "check : <INPUT TYPE='checkbox' checked=checked/><br/>"   +
                         "</FORM></BODY></HTML>"; 

            properties.put(IHtmlToPdfTransformer.PDF_RENDERER_CLASS,
                    IHtmlToPdfTransformer.FLYINGSAUCER_PDF_RENDERER);
            //properties.put(IHtmlToPdfTransformer.FOP_TTF_FONT_PATH, fontPath);
            converter.convertToPdf(str,
                IHtmlToPdfTransformer.A4P, headerFooterList, "file://c:/temp/", out,
                properties);
            out.flush();
            out.close();
    }
}
4个回答

7

您是否正在生成HTML?

如果是这样,那么您可以使用Unicode的“选票方框”字符,而不是使用HTML复选框。该字符为&#x2610;,它只是一个空框,您无法通过电子方式勾选或取消勾选它;但如果PDF文件用于打印,则人们当然可以使用笔或铅笔来勾选它。

例如:

     String str = "<HTML><HEAD></HEAD><BODY><H1>Testing</H1><FORM>" + 
               "check : &#x2610;<br/>" +
               "</FORM></BODY></HTML>";

请注意,只有在您的PDF中使用Unicode字体时,此方法才能正常工作;我认为iText不会使用Unicode字体,除非您告诉它使用。

单选按钮有类似的吗? - Ashish

4

你可能会很遗憾。

用于解析html标签的“htmlWorker”似乎不支持“input”标签,这可能导致问题。

public static final String tagsSupportedString = "ol ul li a pre font span br p div body table td th tr i b u sub sup em strong s strike h1 h2 h3 h4 h5 h6 img";

您可以从这里访问“HtmlWorker”的源代码。 http://www.java2s.com/Open-Source/Java-Document/PDF/pdf-itext/com/lowagie/text/html/simpleparser/HTMLWorker.java.htm
就是从这个源代码中,我找到了答案。
 public void startElement(String tag, HashMap h) {
         if (!tagsSupported.containsKey(tag))
                return; //return if tag not supported
 // ...
}

1
我更喜欢谷歌代码搜索,但那也可以。 代码搜索:\m/ >.< \m/ - Mark Storer

3
使用iText从HTML创建PDF存在一些问题。我建议使用飞行器库来完成此项任务。它在后台也使用了iText。

飞碟支持<input>吗? - Mark Storer
我不确定具体支持哪些功能,但它支持大多数HTML特性。过去我在API中仅用于HTML和PDF报告。另外,如果您只想在PDF中显示一个输入元素(即它不是可填写表单),您可以使用div并通过CSS设置其样式。 - saban
我已经使用YAHP使其正常工作,它使用FlyingSaucer/Itext,我已经在我的问题中更新了解决方案。 - RealHowTo
是的,我尝试过YAHP...它真的很酷。我不明白为什么像FS这样著名的库没有支持HTML中简单标签的能力。 - SRy

2
我所知道的唯一替代方案是对iText进行黑客攻击。新的XMLWorker应该比旧方式(HTMLWorker)更加可扩展,但仍然不容易。可能会有一些神奇的样式标签可以传递进来,在PdfPageEventHandler的“通用标签”中显示,让我们看看...通过阅读代码,似乎样式或属性“generictag”将通过setGenericTag()方法传播到text.Chunk对象中。因此,您需要将不支持的标记XSLT转换为带有“generictag”属性的div/p/whatever,该属性是一个字符串,用于编码您需要重新创建原始元素的信息。在PdfPageEventHandler的OnGenericTag函数中,您必须解析该标记并重新创建您正在尝试重新创建的任何内容。


这个想法疯狂到足以奏效!

请注意我并没有亲自尝试过。如果“generictag”出现问题,你就只能自己动手修改iText(或者转向使用Flying Saucer,或者等待XMLWorker的进一步优化)。 - Mark Storer
飞碟这个库有趣的地方是表单元素的代码被注释了!我会看一下新的 iText XMLWorker。 - RealHowTo
很抱歉,XMLWorker没有包含将表单元素映射到PDF的功能,但是添加一个能够理解表单元素的TagProcessor实现并不难。 - Redlab

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接