1

我正在尝试通过eclipse使用itext和java执行以下操作。我需要创建一个PDF,其中将包含从数据库中检索到的多项选择题。检索到的数据是html标签的形式,因此我正在使用xml worker 来解析它。我能够从数据库中一一检索问题并将其添加到 pdf 中。但问题是它只占用页面的一侧,而我需要问题覆盖 a 的 2 列页。

当到达第一个 PDF 页面的末尾时,它应该利用第一个 PDF 页面的右上角添加问题。只有当页面的左侧和右侧都被完全使用时,它才应该移动到下一个 PDF 页面。

现在我设法使用 ColumnText 在 2 列中获取 html 数据。但我现在面临的问题是从数据库中检索到的问题没有按预期的格式显示。每个问题都显示在一行上。

我输入的问题是这种格式:

1)什么是2+2=?

a2

b)4

c)8

d)15

我希望pdf上的输出应该如上。

但是我得到以下输出:

1)什么是2+2=?a)2b)4c)8d)15

我如何保留 html 格式?????????

到目前为止,这是我的代码:

 import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;

import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.List;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.draw.LineSeparator;
import com.itextpdf.tool.xml.ElementHandler;
import com.itextpdf.tool.xml.ElementList;
import com.itextpdf.tool.xml.Pipeline;
import com.itextpdf.tool.xml.Writable;
import com.itextpdf.tool.xml.XMLWorker;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import com.itextpdf.tool.xml.html.Tags;
import com.itextpdf.tool.xml.parser.XMLParser;
import com.itextpdf.tool.xml.pipeline.WritableElement;
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 ColumnTextExample {
    public static final float[][] COLUMNS = {
         { 36, 36, 224, 579 } , { 230, 36, 418, 579 }

        };
public static void main(String[] args)throws IOException, DocumentException, ClassNotFoundException, SQLException {
        // TODO Auto-generated method stub
        Document document = new Document(PageSize.A4.rotate());

        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("C:\\columns.pdf"));

        document.open();


        Class.forName("com.mysql.jdbc.Driver");
        Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test3", "root", "root");
        Statement st=con.createStatement();
        ResultSet rs=st.executeQuery("select * from exam2");
        int size=0;
        while (rs.next()){
        size++;
        };

        ResultSet rs1=st.executeQuery("select * from exam2");
        String[] myStringArray = new String[size];
        int i=0;
        while (rs1.next()){
           myStringArray[i]=rs1.getString("paper");
           i++;
     }

        ColumnText ct = new ColumnText(writer.getDirectContent());
        for (String article : myStringArray) {

           ct.addElement(createPhrase(article,writer,document));

            ct.addElement(Chunk.NEWLINE);
            document.add(Chunk.NEWLINE);
     }
        ct.setAlignment(Element.ALIGN_CENTER);
        ct.setExtraParagraphSpace(55);
        ct.setLeading(0, 1.2f);
        ct.setFollowingIndent(27);
        int linesWritten = 0;
        int column = 0;
        int status = ColumnText.START_COLUMN;
        while (ColumnText.hasMoreText(status)) {
            ct.setSimpleColumn(
                    COLUMNS[column][0], COLUMNS[column][1],
                    COLUMNS[column][2], COLUMNS[column][3]);
            ct.setYLine(COLUMNS[column][3]);
            status = ct.go();
            linesWritten += ct.getLinesWritten();
            column = Math.abs(column - 1);
            if (column == 0)
                document.newPage();
        }

        ct.addElement(new Phrase("Lines written: " + linesWritten));
        ct.go();
        document.close();
    }
 public static  Phrase createPhrase(String myString, PdfWriter writer, Document document) throws IOException, DocumentException {
        Phrase p = new Phrase();
        String myString2=myString+"<html><body><br></br></body></html>";
        String k="<br></br>";
        XMLWorkerHelper xwh = XMLWorkerHelper.getInstance();
        InputStream is = new ByteArrayInputStream(myString.getBytes());
        ElementList myList = new ElementList();
        ElementList myList1 = new ElementList();
      xwh.parseXHtml(myList,new StringReader(myString2));

      p.addAll(myList);

  return p;
}
    }

当我使用XMLWorkerHelper.getInstance().parseXHtml(writer, document, new StringReader(name1));时,我能够保留 html 格式,例如换行符。

下面的代码帮助我从数据库中检索 html 数据并在保留格式的同时对其进行解析。但是它在单个列中打印到 pdf

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.InputStream;
import java.io.StringReader;

import com.itextpdf.text.Document;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfWriter;
import  com.itextpdf.tool.xml.XMLWorkerHelper;
import java.io.ByteArrayInputStream;
import java.sql.*;


public class GeneratePDF {
    public static void main(String[] args) {
        try {
             OutputStream file = new FileOutputStream(new File("C:\\Test.pdf"));
            Document document = new Document();
            PdfWriter writer = PdfWriter.getInstance(document, file);
            document.open();

                 Class.forName("com.mysql.jdbc.Driver");
                   Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test3", "root", "root");
                   Statement st=con.createStatement();

                   ResultSet rs=st.executeQuery("select paper from exam2 ");
                   String name1="";
                   while (rs.next()){
                       String name = rs.getString("paper");
                       //out.println(name);
                       name1=name;


            /*String k="<h1 style='text-align: center;'><strong>Maths&nbsp;Question2 Paper</strong></h1>"+
"<pre><strong>1)What is the sum of 2+2??<br /></strong><strong>a)3<br /></strong><strong>b)5<br /></strong><strong>c)4<br /></strong><strong>d)1</strong></pre>"+
"<pre><strong>2)What is the sum of 5+2??<br /></strong><strong>a)3<br />b)5<br />c)7<br />d)1</strong></pre>"+
"<pre>&nbsp;</pre>";*/
                   System.out.println(name1);

            //InputStream is = new ByteArrayInputStream(name1.getBytes());
            XMLWorkerHelper.getInstance().parseXHtml(writer, document, new StringReader(name1));
                   }


            document.close();
            file.close();
        } catch (Exception e) {
            e.printStackTrace();
}}} 
4

1 回答 1

0

您正在将 HTML 解析为Document. 这意味着您希望 iText 使用由页面大小(在您的情况下为 A4)和页边距(在您的情况下为每侧 36pt)定义的一列来组织一页上的所有内容。

如果你想以不同的方式组织内容,你应该使用parseXHTML()接受一个ElementHandleras 参数并传递一个ElementList对象的方法。然后,此列表将包含您可以提供给对象的List对象。使用该类,您可以在页面上定义多个矩形,并使用该方法将.ElementColumnTextColumnTextgo()ElementList

于 2013-09-22T09:33:42.217 回答