我如何使用PDFbox创建固定宽度的段落? [英] How can I create fixed-width paragraphs with PDFbox?

查看:301
本文介绍了我如何使用PDFbox创建固定宽度的段落?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以像这样插入简单文本:

  document = new PDDocument(); 
page = new PDPage(PDPage.PAGE_SIZE_A4);
document.addPage(page);
PDPageContentStream content = new PDPageContentStream(document,page);
content.beginText();
content.moveTextPositionByAmount(10,10);
content.drawString(test text);
content.endText();
content.close();

但是如何使用width属性创建一段类似于HTML的段落?

 < p style =width:200px;>测试文字< / p> 


解决方案

这个答案无法在某些文本中插入换行符,并使PDF正确显示(无论是使用PDFBox还是其他),所以我相信自动换行文本以适应一些宽度也可能是它不能自动完成的事情。 (此外,有很多方法可以包装文本 - 仅包含整个文字,将它们分成较小的部分等)。

回答另一个问题(关于居中字符串)给出了一些关于如何自己完成此操作的提示。假设您编写了一个函数 possibleWrapPoints(String):int [] 来列出文本中的所有点,可以进行自动换行(不包括零,包括文本长度) ,一种可能的解决方案可能是:

  PDFont font = PDType1Font.HELVETICA_BOLD; //或者你想要的任何字体。 
int fontSize = 16; //或者任何你想要的字体大小。
int paragraphWidth = 200;
String text =test text;

int start = 0;
int end = 0;
int height = 10;
for(int i:possibleWrapPoints(text)){
float width = font.getStringWidth(text.substring(start,i))/ 1000 * fontSize;
if(start< end& width> paragraphWidth){
//绘制部分文字并增加高度
content.moveTextPositionByAmount(10,height);
content.drawString(text.substring(start,end));
height + = font.getFontDescriptor()。getFontBoundingBox()。getHeight()/ 1000 * fontSize;
start = end;
}
end = i;
}
//最后一段文字
content.moveTextPositionByAmount(10,height);
content.drawString(text.substring(start));



possibleWrapPoints 的一个例子允许包装在任何不属于单词的地方(参考),可能是:


  int [] possibleWrapPoints(String text){
String [] split = text.split((?<= \\W)) ;
int [] ret = new int [split.length];
ret [0] = split [0] .length();
for(int i = 1; i< split.length; i ++)
ret [i] = ret [i-1] + split [i] .length();
return ret;

更新:一些附加信息:




  • PDF文件格式设计为在不同情况下看起来相同,在PDF编辑器/创建者,但不在PDF文件本身中。出于这个原因,大多数低级工具倾向于专注于处理文件格式本身,并且避免这种情况。

  • 有手段进行此转换。一个例子是 Platypus (对于Python来说), do 可以轻松创建段落,并依靠较低级别的 ReportLab 功能来完成实际的PDF渲染。我并不知道类似的PDFBox工具,但这篇文章给出了一些关于如何在Java环境中使用免费提供的工具将HTML内容转换为PDF。没有尝试过,但我在这里发布,因为它可能是有用的(如果我上面的手工制作的尝试是不够的)。 $ b

    I can insert simple text like this:

    document = new PDDocument();
    page = new PDPage(PDPage.PAGE_SIZE_A4);
    document.addPage(page);
    PDPageContentStream content = new PDPageContentStream(document, page);
    content.beginText();
    content.moveTextPositionByAmount (10 , 10);
    content.drawString ("test text");
    content.endText();
    content.close();
    

    but how can I create a paragraph similar to HTML using the width attribute?

    <p style="width:200px;">test text</p>
    

    解决方案

    According to this answer it's not possible to insert line breaks into some text and have PDF display it correctly (whether using PDFBox or something else), so I believe auto-wrapping some text to fit in some width may also be something it can't do automatically. (besides, there are many ways to wrap a text - whole words only, break them in smaller parts, etc)

    This answer to another question (about centering a string) gives some pointers on how to do this yourself. Assuming you wrote a function possibleWrapPoints(String):int[] to list all points in the text a word wrap can happen (excluding "zero", including "text length"), one possible solution could be:

    PDFont font = PDType1Font.HELVETICA_BOLD; // Or whatever font you want.
    int fontSize = 16; // Or whatever font size you want.
    int paragraphWidth = 200;
    String text = "test text";
    
    int start = 0;
    int end = 0;
    int height = 10;
    for ( int i : possibleWrapPoints(text) ) {
        float width = font.getStringWidth(text.substring(start,i)) / 1000 * fontSize;
        if ( start < end && width > paragraphWidth ) {
            // Draw partial text and increase height
            content.moveTextPositionByAmount(10 , height);
            content.drawString(text.substring(start,end));
            height += font.getFontDescriptor().getFontBoundingBox().getHeight() / 1000 * fontSize;
            start = end;
        }
        end = i;
    }
    // Last piece of text
    content.moveTextPositionByAmount(10 , height);
    content.drawString(text.substring(start));
    

    One example of possibleWrapPoints, that allow wrapping at any point that's not part of a word (reference), could be:

    int[] possibleWrapPoints(String text) {
        String[] split = text.split("(?<=\\W)");
        int[] ret = new int[split.length];
        ret[0] = split[0].length();
        for ( int i = 1 ; i < split.length ; i++ )
            ret[i] = ret[i-1] + split[i].length();
        return ret;
    }
    

    Update: some additional info:

    • The PDF file format was designed to look the same in different situations, functionality like the one you requested makes sense in a PDF editor/creator, but not in the PDF file per se. For this reason, most "low level" tools tend to concentrate on dealing with the file format itself and leave away stuff like that.

    • Higher level tools OTOH usually have means to make this conversion. An example is Platypus (for Python, though), that do have easy ways of creating paragraphs, and relies on the lower level ReportLab functions to do the actual PDF rendering. I'm unaware of similar tools for PDFBox, but this post gives some hints on how to convert HTML content to PDF in a Java environment, using freely available tools. Haven't tried them myself, but I'm posting here since it might be useful (in case my hand-made attempt above is not enough).

    这篇关于我如何使用PDFbox创建固定宽度的段落?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆