Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何将页面高度调整为内容高度?_Java_Height_Itext_Itextpdf - Fatal编程技术网

Java 如何将页面高度调整为内容高度?

Java 如何将页面高度调整为内容高度?,java,height,itext,itextpdf,Java,Height,Itext,Itextpdf,我正在为我的项目使用iTextPDF+FreeMarker。基本上,我用FreeMarker加载并填充HTML模板,然后用iTextPDF的XMLWorker将其呈现为pdf 模板为: <html> <body style="font-family; ${fontName}"> <table> <tr> <td style="text-align: right"&

我正在为我的项目使用iTextPDF+FreeMarker。基本上,我用FreeMarker加载并填充HTML模板,然后用iTextPDF的
XMLWorker
将其呈现为pdf

模板为:

<html>
    <body style="font-family; ${fontName}">
        <table>
            <tr>
                <td style="text-align: right">${timestampLabel}&nbsp;</td>
                <td><b>${timestampValue}</b></td>
            </tr>
            <tr>
                <td style="text-align: right">${errorIdLabel}&nbsp;</td>
                <td><b>${errorIdValue}</b></td>
            </tr>
            <tr>
                <td style="text-align: right">${systemIdLabel}&nbsp;</td>
                <td><b>${systemIdValue}</b></td>
            </tr>
            <tr>
                <td style="text-align: right">${descriptionLabel}&nbsp;</td>
                <td><b>${descriptionValue}</b></td>
            </tr>
        </table>
    </body>
</html>
制作的文件是:

如果我用

errorId = "ERROR-01"
systemId = "SYSTEM-01"
description = "A SHORT DESCRIPTION OF THE ISSUE. THIS IS MULTILINE AND IT SHOULD STAY ALL IN THE SAME PDF PAGE."
制作的文件是:

如你所见,在上一份文件中,我有两页。我想只有一个页面,根据内容高度改变其高度


iText是否可以这样做?

在向页面添加内容后,您不能更改页面大小。解决此问题的一种方法是分两步创建文档:首先创建文档以添加内容,然后操纵文档以更改页面大小。如果我有时间立即回答,那将是我的第一个答复

现在我花了更多的时间来考虑,我找到了一个更好的解决方案,不需要两次通过。看看

在本例中,我首先使用以下方法将内容解析为
Element
对象列表:

public ElementList parseHtml(String html, String css) throws IOException {
    // CSS
    CSSResolver cssResolver = new StyleAttrCSSResolver();
    CssFile cssFile = XMLWorkerHelper.getCSS(new ByteArrayInputStream(css.getBytes()));
    cssResolver.addCss(cssFile);

    // HTML
    CssAppliers cssAppliers = new CssAppliersImpl(FontFactory.getFontImp());
    HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
    htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
    htmlContext.autoBookmark(false);

    // Pipelines
    ElementList elements = new ElementList();
    ElementHandlerPipeline end = new ElementHandlerPipeline(elements, null);
    HtmlPipeline htmlPipeline = new HtmlPipeline(htmlContext, end);
    CssResolverPipeline cssPipeline = new CssResolverPipeline(cssResolver, htmlPipeline);

    // XML Worker
    XMLWorker worker = new XMLWorker(cssPipeline, true);
    XMLParser p = new XMLParser(worker);
    p.parse(new ByteArrayInputStream(html.getBytes()));

    return elements;
}
注意:我多次复制/粘贴此方法,因此决定在
XMLWorkerHelper
类中将其作为静态方法。它将在下一个iText版本中提供

重要提示:我已经完成了承诺,现在XML Worker版本中提供了此方法

出于测试目的,我对HTML和CSS使用了静态
String
值:

public static final String HTML = "<table>" +
    "<tr><td class=\"ra\">TIMESTAMP</td><td><b>2014-11-28 11:06:09</b></td></tr>" +
    "<tr><td class=\"ra\">ERROR ID</td><td><b>ERROR-01</b></td></tr>" +
    "<tr><td class=\"ra\">SYSTEM ID</td><td><b>SYSTEM-01</b></td></tr>" +
    "<tr><td class=\"ra\">DESCRIPTION</td><td><b>TEST WITH A VERY, VERY LONG DESCRIPTION LINE THAT NEEDS MULTIPLE LINES</b></td></tr>" +
    "</table>";
public static final String CSS = "table {width: 200pt; } .ra { text-align: right; }";
public static final String DEST = "results/xmlworker/html_page_size.pdf";
或者,从XML Worker 5.5.4开始:

ElementList el = XMLWorkerHelper.parseToElementList(HTML, CSS);
到目前为止,一切顺利。我没有告诉你任何你不知道的事情,除了这个:我现在知道了 要使用此
el
两次:

  • 我将在模拟模式下将列表添加到
    列文本中。此
    ColumnText
    尚未绑定到任何文档或编写器。这样做的唯一目的是了解我在垂直方向上需要多少空间
  • 我将把该列表添加到
    列文本中,以供实际使用。这个
    ColumnText
    将完全适合我使用模拟模式中获得的结果定义的页面大小
  • 一些代码将阐明我的意思:

    // I define a width of 200pt
    float width = 200;
    // I define the height as 10000pt (which is much more than I'll ever need)
    float max = 10000;
    // I create a column without a `writer` (strange, but it works)
    ColumnText ct = new ColumnText(null);
    ct.setSimpleColumn(new Rectangle(width, max));
    for (Element e : el) {
        ct.addElement(e);
    }
    // I add content in simulation mode
    ct.go(true);
    // Now I ask the column for its Y position
    float y = ct.getYLine();
    
    上述代码仅对一件事有用:获取将用于定义
    文档
    页面大小的
    y
    值,以及将实际添加的
    ColumnText
    的列维度:

    Rectangle pagesize = new Rectangle(width, max - y);
    // step 1
    Document document = new Document(pagesize, 0, 0, 0, 0);
    // step 2
    PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));
    // step 3
    document.open();
    // step 4
    ct = new ColumnText(writer.getDirectContent());
    ct.setSimpleColumn(pagesize);
    for (Element e : el) {
        ct.addElement(e);
    }
    ct.go();
    // step 5
    document.close();
    

    请下载完整代码并更改
    HTML
    的值。您将看到这会导致不同的页面大小。

    iText的创建者正在回答我关于iText的问题。太好了!!非常感谢,我会在回家后尝试这个非常有用的例子,很快适应了段落文本,谢谢。您创建的任何示例是否有索引?是否有任何方法实现相同的索引,但将HTML和CSS放在一个字符串中?当我从服务器获取完整的HTML文档时,我没有找到任何示例。你能分享一下吗?我有一个来自服务器的html文档,需要根据自定义字体的内容将其转换为带高度的PDF。@SalmanNazir为什么不发布一个问题来说明您所拥有的内容?高举2014年的问题不是获得答案的方式。
    ElementList el = XMLWorkerHelper.parseToElementList(HTML, CSS);
    
    // I define a width of 200pt
    float width = 200;
    // I define the height as 10000pt (which is much more than I'll ever need)
    float max = 10000;
    // I create a column without a `writer` (strange, but it works)
    ColumnText ct = new ColumnText(null);
    ct.setSimpleColumn(new Rectangle(width, max));
    for (Element e : el) {
        ct.addElement(e);
    }
    // I add content in simulation mode
    ct.go(true);
    // Now I ask the column for its Y position
    float y = ct.getYLine();
    
    Rectangle pagesize = new Rectangle(width, max - y);
    // step 1
    Document document = new Document(pagesize, 0, 0, 0, 0);
    // step 2
    PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));
    // step 3
    document.open();
    // step 4
    ct = new ColumnText(writer.getDirectContent());
    ct.setSimpleColumn(pagesize);
    for (Element e : el) {
        ct.addElement(e);
    }
    ct.go();
    // step 5
    document.close();