Java 更改页面时出现PdfBox问题
我不太喜欢问这样的问题,但我已经花了整整三天的时间试图解决我代码中的这个错误 我知道这是一个逻辑问题,我知道如何在头脑中解决它,但当涉及到将我的想法转化为代码时,我就是无法让它按我想要的方式工作 我正在做一个合同背书(合同的修改),它比较了两个表中的数据,如果其中任何一个表发生了变化,那么它只绘制了这些信息 有时,信息会发生变化,例如条件变长或变短,这就是问题所在 我做了一个算法,当它完成绘制信息时,得到最小Y坐标,但当我更改页面时,Y坐标必须重置为Java 更改页面时出现PdfBox问题,java,pdf,pdf-generation,rendering,pdfbox,Java,Pdf,Pdf Generation,Rendering,Pdfbox,我不太喜欢问这样的问题,但我已经花了整整三天的时间试图解决我代码中的这个错误 我知道这是一个逻辑问题,我知道如何在头脑中解决它,但当涉及到将我的想法转化为代码时,我就是无法让它按我想要的方式工作 我正在做一个合同背书(合同的修改),它比较了两个表中的数据,如果其中任何一个表发生了变化,那么它只绘制了这些信息 有时,信息会发生变化,例如条件变长或变短,这就是问题所在 我做了一个算法,当它完成绘制信息时,得到最小Y坐标,但当我更改页面时,Y坐标必须重置为700f,然后从那里重新开始绘制 我使用的代码
700f
,然后从那里重新开始绘制
我使用的代码最初是由另一个程序员编写的,他已经不在这里了,我不知道如何处理PDF
但我认为这些方法可以帮助你帮助我
我如何在PDF上比较和绘制信息的示例:
sOffA
和sOffE
是来自名为SubscriptionOffer
的类的对象,a
代表Agreement
,而E
代表背书
。背书是MySQL上的表协议
的副本,但信息已修改。也许这是无关的信息,也许不是
if (!nullOrEmpty(sOffA.getGeneralConditions()) &&
!nullOrEmpty(sOffE.getGeneralConditions())) {
if (!getStringValue(sOffA.getGeneralConditions()).
equals(getStringValue(sOffE.getGeneralConditions()))) {
minYs[0] = pdf.rText(LEFT_MARGIN, y, 10,
constants.generalConditions(),
getStringValue(sOffA.
getGeneralConditions()));
minYs[1] = pdf.rText(HALF_PAGE, y, 10,
constants.generalConditions(),
getStringValue(sOffE.
getGeneralConditions()));
y = checkY(pdf, minYs);
}
} else if (nullOrEmpty(sOffA.getGeneralConditions()) &&
!nullOrEmpty(sOffE.getGeneralConditions())) {
minYs[0] = pdf.rText(LEFT_MARGIN, y, 10, "", "");
minYs[1] = pdf.rText(HALF_PAGE, y, 10,
constants.generalConditions(),
getStringValue(sOffE.
getGeneralConditions()));
y = checkY(pdf, minYs);
} else if (!nullOrEmpty(sOffA.getGeneralConditions()) &&
nullOrEmpty(sOffE.getGeneralConditions())) {
minYs[0] = pdf.rText(LEFT_MARGIN, y, 10,
constants.generalConditions(),
getStringValue(sOffA.
getGeneralConditions()));
minYs[1] = pdf.rText(HALF_PAGE, y, 10, "", "");
y = checkY(pdf, minYs);
}
我使用的阵列如下所示:
private float[] minYs = new float[] {700, 700, 700, 700, 700, 700, 700,
700, 700};
这是一种检查Y的方法,它检查数组中哪个Y(如上所示)是最低的,然后将所有元素的整个数组重新启动回700f。然后检查最低Y坐标下的空间是否足以绘制下一个项目
private float checkY(PdfRenderingEndorsement pdf, float... ys) throws Exception {
float y2 = getMinY(pdf, ys);
for (int i = 0; i < ys.length; i++) {
ys[i] = 700;
}
y2 = pdf.checkContentStream(y2, 5, 10);
return y2;
}
获取对象的字符串值并检查它们是否为null或空的方法:
private boolean nullOrEmpty(String s) {
return s == null || s.isEmpty();
}
private String getStringValue(Object o) {
if (o == null) {
return "";
}
return getStringValue(o, null);
}
private String getStringValue(Object o, Class< ? extends Unit> clazz) {
if (o instanceof Boolean) {
Boolean bd = (Boolean) o;
if (bd) {
return constants.getString("dbeditorYes");
} else {
return constants.getString("dbeditorNo");
}
} else if (o instanceof Date) {
Date date = (Date) o;
DateFormat df = new SimpleDateFormat(DateConstants.DATE_FORMAT);
return df.format(date);
} else if (o instanceof Enum) {
Enum en = (Enum) o;
return constants.enumMap().get(en.toString());
} else if (o instanceof Integer) {
Integer integer = (Integer) o;
if (clazz == null) {
return String.valueOf(integer);
} else {
Unit entry = unitSvc.get(clazz, integer);
String[] params = entry.toString().split("\\|");
String label = params.length == 1 ? params[0] : params[1];
return label;
}
} else if (o instanceof BigDecimal) {
BigDecimal bd = (BigDecimal) o;
DecimalFormat df = new DecimalFormat("#,##0");
df = new DecimalFormat("#,##0.00");
return df.format(bd);
} else if (o instanceof Float) {
Float bd = (Float) o;
DecimalFormat df = new DecimalFormat("#,##0");
df = new DecimalFormat("#,##0.00");
return df.format(bd);
} else if (o instanceof String) {
String td = (String) o;
return td;
}
return "";
}
这是每个方法的原始()输出的一部分
如果您看不到PDF,请告诉我,但这里还有一些截图:
这是一个在getMinY
方法上使用非注释代码的输出
这一修改的结果如下:
正如您可以看到的,第一个输出“跳转”到下一页,因为我们假设“Texto de Poliza”右侧的文本以Y coord 680、670或类似的形式结束,但在左侧,我绘制了一个空字段(“”)
,以90或100结尾,接近这些数字
然后比较100<670?是的,然后我取50到100,它比我的下页边距
(60)低,所以它关闭了实际页面(现在是文本结束的地方,但认为它在前面的页面上),并创建了一个新页面
差不多一年前我问过一个类似的问题,这些类几乎都是这些文件的副本,但我的逻辑上的这个错误只出现在这些文件中,因为数据处理方式有点不同
在那一堆文字之后,我希望有人能读到它,并帮我一把,也许我遗漏了一个重要的部分,但找不到它
提前谢谢
编辑
在将@mkl的答案添加到我的方法中之后,我发现当双方的信息都没有改变时,就会产生一个缺口,看起来也不太好
这就是我将数据发送到PdfRenderingEndorsementAlternative
的方式:
for (String[] data: sOppData) {
//float y = renderer.getPreviousBandBase;
for (int i = 0; i < data.length - 2; i += 3) {
if (!nullOrEmpty(data[i + 1]) &&
!nullOrEmpty(data[i + 2])) {
if (!data[i + 1].equals(data[i + 2])) {
renderer.
render(new BandColumn(leftHalfPageField,
data[i], data[i + 1]),
new BandColumn(rightHalfPageField,
data[i], data[i + 2])
);
}
} else if (nullOrEmpty(data[i + 1]) &&
!nullOrEmpty(data[i + 2])) {
renderer.
render(new BandColumn(leftHalfPageField,
"", ""),
new BandColumn(rightHalfPageField,
data[i], data[i + 2])
);
} else if (!nullOrEmpty(data[i + 1]) &&
nullOrEmpty(data[i + 2])) {
renderer.
render(new BandColumn(leftHalfPageField,
data[i], data[i + 1]),
new BandColumn(rightHalfPageField,
"", "")
);
}
}
//float y2 = renderer.getPreviousBandBase();
/*if (y2 < y)
renderer.gap(20);
*/
renderer.gap(20);
}
正如已经在评论中暗示的(实际上已经在您的评论中),我认为渲染类的整个体系结构需要大修。基于您的PdfRenderingEndorsement
我创建了以下类PdfRenderingEndorsementAlternative
,它代表了该渲染的另一种方法:
public class PdfRenderingEndorsementAlternative implements AutoCloseable
{
//
// misc constants
//
static final int FIELD_WIDTH = 70;
static final int HALF_WIDTH = 325;
static final int TEXT_WIDTH = 410;
static final float BOTTOM_MARGIN = 70;
static final int LEFT_MARGIN = 50;
//
// rendering
//
public void gap(int size)
{
previousBandBase-=size;
}
public void render(BandColumn... columns) throws IOException
{
if (content == null)
newPage();
final List<Chunk> chunks = new ArrayList<Chunk>();
for (BandColumn column : columns)
{
chunks.addAll(column.toChunks());
}
float offset = 0;
while (!chunks.isEmpty())
{
float lowestAddedY = previousBandBase;
float highestBaseBeforeNonAdded = Float.NEGATIVE_INFINITY;
List<Chunk> added = new ArrayList<Chunk>();
for (Chunk chunk: chunks)
{
float y = previousBandBase + chunk.y + offset;
if (y >= BOTTOM_MARGIN)
{
content.beginText();
content.setFont(chunk.font, 9);
content.moveTextPositionByAmount(chunk.x, y);
content.drawString(chunk.text);
content.endText();
// draw
if (y < lowestAddedY)
lowestAddedY = y;
added.add(chunk);
}
else
{
float baseBefore = chunk.y + chunk.space;
if (baseBefore > highestBaseBeforeNonAdded)
highestBaseBeforeNonAdded = baseBefore;
}
}
chunks.removeAll(added);
if (!chunks.isEmpty())
{
newPage();
offset = -highestBaseBeforeNonAdded;
}
else
{
previousBandBase = lowestAddedY;
}
}
}
static public class BandColumn
{
public enum Layout
{
headerText(150, TEXT_WIDTH, 0, 10),
leftHalfPageField(LEFT_MARGIN, FIELD_WIDTH, HALF_WIDTH - 2 * FIELD_WIDTH - 10, 10),
rightHalfPageField(HALF_WIDTH, FIELD_WIDTH, HALF_WIDTH - 2 * FIELD_WIDTH - 10, 10);
Layout(float x, int fieldWidth, int valueWidth, int space)
{
this.x = x;
this.fieldWidth = fieldWidth;
this.valueWidth = valueWidth;
this.space = space;
}
final float x;
final int fieldWidth, valueWidth, space;
}
public BandColumn(Layout layout, String labelField, String value)
{
this(layout.x, layout.space, labelField, value, layout.fieldWidth, layout.valueWidth);
}
public BandColumn(float x, int space, String labelField, String value, int fieldWidth, int valueWidth)
{
this.x = x;
this.space = space;
this.labelField = labelField;
this.value = value;
this.fieldWidth = fieldWidth;
this.valueWidth = valueWidth;
}
List<Chunk> toChunks() throws IOException
{
final List<Chunk> result = new ArrayList<Chunk>();
result.addAll(toChunks(0, fieldWidth, PDType1Font.TIMES_BOLD, labelField));
result.addAll(toChunks(10 + fieldWidth, valueWidth, PDType1Font.TIMES_ROMAN, value));
return result;
}
List<Chunk> toChunks(int offset, int width, PDFont font, String text) throws IOException
{
if (text == null || text.length() == 0)
return Collections.emptyList();
final List<Chunk> result = new ArrayList<Chunk>();
float y = -space;
List<String> rows = getRows(text, width, font);
for (String row: rows)
{
result.add(new Chunk(x+offset, y, space, font, row));
y-= space;
}
return result;
}
final float x;
final int space, fieldWidth, valueWidth;
final String labelField, value;
}
//
// constructor
//
public PdfRenderingEndorsementAlternative(PDDocument doc, InputStream logo,
String[] header) throws IOException
{
this.doc = doc;
this.header = header;
logoImg = new PDJpeg(doc, logo);
}
//
// AutoCloseable implementation
//
@Override
public void close() throws IOException
{
if (content != null)
{
content.close();
content = null;
}
}
//
// helper methods
//
void newPage() throws IOException
{
close();
PDPage page = new PDPage(PDPage.PAGE_SIZE_LETTER);
doc.addPage(page);
content = new PDPageContentStream(doc, page);
content.drawImage(logoImg, 50, 720);
content.setLineWidth(.5f);
content.setNonStrokingColor(Color.GRAY);
content.drawLine(50, 710, 562, 710);
previousBandBase = 770;
render(new BandColumn(BandColumn.Layout.headerText, "ENDOSO", null));
for (String head: header)
render(new BandColumn(BandColumn.Layout.headerText, head, null));
content.setNonStrokingColor(Color.BLACK);
previousBandBase = 680;
}
// original method
static List<String> getRows(String text, int width, PDFont font) throws IOException
{
float textWidth = font.getStringWidth(text) / 1000f * 9f;
ArrayList<String> result = new ArrayList<String>();// Lists.newArrayList();
if (textWidth < width)
{
result.add(text);
return result;
}
float spaceWidth = font.getStringWidth(" ") / 1000f * 9f;
String[] paragraphs = text.split("\n|\r\n|\r");
for (String paragraph : paragraphs)
{
float pWidth = font.getStringWidth(paragraph) / 1000f * 9f;
if (pWidth < width)
{
result.add(paragraph);
continue;
}
float widthCount = 0f;
String[] words = paragraph.trim().split(" ");
StringBuilder sb = new StringBuilder();
for (int j = 0; j < words.length; j++)
{
if (words[j].trim().length() == 0)
{
continue;
}
float wWidth = font.getStringWidth(words[j]) / 1000f * 9f;
float totalWidth = widthCount + wWidth + spaceWidth;
if (totalWidth < width + spaceWidth)
{
sb.append(words[j]);
sb.append(" ");
widthCount = totalWidth;
}
else
{
result.add(sb.toString().trim());
sb = new StringBuilder();
sb.append(words[j]);
sb.append(" ");
widthCount = totalWidth - widthCount;
}
}
result.add(sb.toString().trim());
}
return result;
}
//
// helper classes
//
static class Chunk
{
Chunk(float x, float y, int space, PDFont font, String text)
{
this.x = x;
this.y = y;
this.space = space;
this.font = font;
this.text = text;
}
final float x, y;
final int space;
final PDFont font;
final String text;
}
//
// members
//
private final PDDocument doc;
private final PDJpeg logoImg;
private final String[] header;
private PDPageContentStream content = null;
private float previousBandBase = 0;
}
()
如您所见,调用者不必再关心y位置,一切都是在renderer类中完成的。结果是:
我使用您的第一个示例PDF中的数据作为输入,结果如下:
正如您所见,没有页面跳转,也没有重叠文本。正如我已经对您的前一个问题进行了评论,我怀疑从rtext内部检查页面切换是否是一个好主意,它应该由某个方法控制,并注意为所有列中的当前条目添加的内容。@mkl您是否有一个示例,或者该方法的另一个问题的链接?或者我能分析的类似的东西?对不起,我迟了回答。谢谢现在我将阅读一些文档并尝试一些方法。我对pdf编程没有那么丰富的经验,所以我犯了很多错误(我不知道如何用pdf做一个简单的“Hello World”,我的意思是不是从0开始)。我已经开始阅读如何用PDFBox和Maven从0开始pdf,我仍然停留在Maven配置上,但一旦我有了一个MCVE,我就会发布它代码>每次在for循环中,不管是否渲染了条目。仅在呈现条目后添加间隙。我以前怎么看不到?我在想一个else{continue}
用于if(!data[I+1].equals(data[I+2])
我将在周一测试它……我正在测试解决方案,我花了一段时间将它调整到项目中,你介意我在4小时内开始一个悬赏(在添加悬赏之前错过时间)吗在周末接受你的答案,这样你就能得到赏金了?顺便说一句,非常感谢你,看到这种方法,我想我是在尝试重新发明轮子(而且是以错误的方式)。无论如何,我将继续尝试配置Maven,以从0创建项目,并学习如何在将来为PDF进行MCVE。您是否介意…-我不介意,但请不要觉得有义务这么做。我希望此代码示例可以帮助您。当然,它对我有帮助。我没有义务,但非常感谢。非常感谢:)我有疑问,你会在哪里检查两边是否都有变化?也就是说,即使信息没有变化,也会产生20的差距。我想用现在的Y和结束的Y,但我想我会回到我的方法中,这会带来
for (String[] data: sOppData) {
//float y = renderer.getPreviousBandBase;
for (int i = 0; i < data.length - 2; i += 3) {
if (!nullOrEmpty(data[i + 1]) &&
!nullOrEmpty(data[i + 2])) {
if (!data[i + 1].equals(data[i + 2])) {
renderer.
render(new BandColumn(leftHalfPageField,
data[i], data[i + 1]),
new BandColumn(rightHalfPageField,
data[i], data[i + 2])
);
}
} else if (nullOrEmpty(data[i + 1]) &&
!nullOrEmpty(data[i + 2])) {
renderer.
render(new BandColumn(leftHalfPageField,
"", ""),
new BandColumn(rightHalfPageField,
data[i], data[i + 2])
);
} else if (!nullOrEmpty(data[i + 1]) &&
nullOrEmpty(data[i + 2])) {
renderer.
render(new BandColumn(leftHalfPageField,
data[i], data[i + 1]),
new BandColumn(rightHalfPageField,
"", "")
);
}
}
//float y2 = renderer.getPreviousBandBase();
/*if (y2 < y)
renderer.gap(20);
*/
renderer.gap(20);
}
private ArrayList<String []> renderSubscriptionOpportunity(
SubscriptionOpp sOppA, SubscriptionOpp sOppE,
ArrayList<Location> lcA, ArrayList<Location> lcE)
throws Exception {
ArrayList <String[]> sOppData = new ArrayList<String[]>();
sOppData.add(new String[] {constants.currencyId(),
getStringValue(sOppA.getCurrencyId(),
Currency.class),
getStringValue(sOppE.getCurrencyId(),
Currency.class)});
sOppData.add(new String[] {constants.contractName(),
getStringValue(sOppA.getContractName()),
getStringValue(sOppE.getContractName())});
sOppData.add(new String[] {constants.mainActivityId(),
getStringValue(sOppA.getMainActivityId(),
MainActivity.class),
getStringValue(sOppE.getMainActivityId(),
MainActivity.class)});
//here add location table
if (lcA.size() > 1 && lcE.size() > 1) {
int lastIdA = 0;
int lastIdE = 0;
int size = lcA.size() >= lcE.size() ? lcA.size() : lcE.size();
LOGGER.trace("size: " + size + " lcA.size(): " + lcA.size() +
" lcE.size(): " + lcE.size());
for (int pos = 1; pos < lcA.size(); pos++) {
StringBuilder aSb = new StringBuilder();
StringBuilder eSb = new StringBuilder();
String valueA = "";
String valueE = "";
if (pos < lcA.size()) {
Country countryA = unitSvc.get(Country.class,
lcA.get(pos).getCountryId());
LOGGER.trace("Entro1");
if (countryA.getId() != lastIdA) {
aSb.append(countryA.getName());
lastIdA = countryA.getId();
} else {
aSb.append("");
}
} else {
aSb.append("");
}
if (pos < lcE.size()) {
Country countryE = unitSvc.get(Country.class,
lcE.get(pos).getCountryId());
LOGGER.trace("Entro2");
if (countryE.getId() != lastIdE) {
eSb.append(countryE.getName());
lastIdE = countryE.getId();
} else {
eSb.append("");
}
} else {
eSb.append("");
}
valueA = aSb.toString();
valueE = eSb.toString();
sOppData.add(new String[] {pos == 1 ? constants.countryId() :
"", valueA, valueE});
}
}
return sOppData;
}
public class PdfRenderingEndorsementAlternative implements AutoCloseable
{
//
// misc constants
//
static final int FIELD_WIDTH = 70;
static final int HALF_WIDTH = 325;
static final int TEXT_WIDTH = 410;
static final float BOTTOM_MARGIN = 70;
static final int LEFT_MARGIN = 50;
//
// rendering
//
public void gap(int size)
{
previousBandBase-=size;
}
public void render(BandColumn... columns) throws IOException
{
if (content == null)
newPage();
final List<Chunk> chunks = new ArrayList<Chunk>();
for (BandColumn column : columns)
{
chunks.addAll(column.toChunks());
}
float offset = 0;
while (!chunks.isEmpty())
{
float lowestAddedY = previousBandBase;
float highestBaseBeforeNonAdded = Float.NEGATIVE_INFINITY;
List<Chunk> added = new ArrayList<Chunk>();
for (Chunk chunk: chunks)
{
float y = previousBandBase + chunk.y + offset;
if (y >= BOTTOM_MARGIN)
{
content.beginText();
content.setFont(chunk.font, 9);
content.moveTextPositionByAmount(chunk.x, y);
content.drawString(chunk.text);
content.endText();
// draw
if (y < lowestAddedY)
lowestAddedY = y;
added.add(chunk);
}
else
{
float baseBefore = chunk.y + chunk.space;
if (baseBefore > highestBaseBeforeNonAdded)
highestBaseBeforeNonAdded = baseBefore;
}
}
chunks.removeAll(added);
if (!chunks.isEmpty())
{
newPage();
offset = -highestBaseBeforeNonAdded;
}
else
{
previousBandBase = lowestAddedY;
}
}
}
static public class BandColumn
{
public enum Layout
{
headerText(150, TEXT_WIDTH, 0, 10),
leftHalfPageField(LEFT_MARGIN, FIELD_WIDTH, HALF_WIDTH - 2 * FIELD_WIDTH - 10, 10),
rightHalfPageField(HALF_WIDTH, FIELD_WIDTH, HALF_WIDTH - 2 * FIELD_WIDTH - 10, 10);
Layout(float x, int fieldWidth, int valueWidth, int space)
{
this.x = x;
this.fieldWidth = fieldWidth;
this.valueWidth = valueWidth;
this.space = space;
}
final float x;
final int fieldWidth, valueWidth, space;
}
public BandColumn(Layout layout, String labelField, String value)
{
this(layout.x, layout.space, labelField, value, layout.fieldWidth, layout.valueWidth);
}
public BandColumn(float x, int space, String labelField, String value, int fieldWidth, int valueWidth)
{
this.x = x;
this.space = space;
this.labelField = labelField;
this.value = value;
this.fieldWidth = fieldWidth;
this.valueWidth = valueWidth;
}
List<Chunk> toChunks() throws IOException
{
final List<Chunk> result = new ArrayList<Chunk>();
result.addAll(toChunks(0, fieldWidth, PDType1Font.TIMES_BOLD, labelField));
result.addAll(toChunks(10 + fieldWidth, valueWidth, PDType1Font.TIMES_ROMAN, value));
return result;
}
List<Chunk> toChunks(int offset, int width, PDFont font, String text) throws IOException
{
if (text == null || text.length() == 0)
return Collections.emptyList();
final List<Chunk> result = new ArrayList<Chunk>();
float y = -space;
List<String> rows = getRows(text, width, font);
for (String row: rows)
{
result.add(new Chunk(x+offset, y, space, font, row));
y-= space;
}
return result;
}
final float x;
final int space, fieldWidth, valueWidth;
final String labelField, value;
}
//
// constructor
//
public PdfRenderingEndorsementAlternative(PDDocument doc, InputStream logo,
String[] header) throws IOException
{
this.doc = doc;
this.header = header;
logoImg = new PDJpeg(doc, logo);
}
//
// AutoCloseable implementation
//
@Override
public void close() throws IOException
{
if (content != null)
{
content.close();
content = null;
}
}
//
// helper methods
//
void newPage() throws IOException
{
close();
PDPage page = new PDPage(PDPage.PAGE_SIZE_LETTER);
doc.addPage(page);
content = new PDPageContentStream(doc, page);
content.drawImage(logoImg, 50, 720);
content.setLineWidth(.5f);
content.setNonStrokingColor(Color.GRAY);
content.drawLine(50, 710, 562, 710);
previousBandBase = 770;
render(new BandColumn(BandColumn.Layout.headerText, "ENDOSO", null));
for (String head: header)
render(new BandColumn(BandColumn.Layout.headerText, head, null));
content.setNonStrokingColor(Color.BLACK);
previousBandBase = 680;
}
// original method
static List<String> getRows(String text, int width, PDFont font) throws IOException
{
float textWidth = font.getStringWidth(text) / 1000f * 9f;
ArrayList<String> result = new ArrayList<String>();// Lists.newArrayList();
if (textWidth < width)
{
result.add(text);
return result;
}
float spaceWidth = font.getStringWidth(" ") / 1000f * 9f;
String[] paragraphs = text.split("\n|\r\n|\r");
for (String paragraph : paragraphs)
{
float pWidth = font.getStringWidth(paragraph) / 1000f * 9f;
if (pWidth < width)
{
result.add(paragraph);
continue;
}
float widthCount = 0f;
String[] words = paragraph.trim().split(" ");
StringBuilder sb = new StringBuilder();
for (int j = 0; j < words.length; j++)
{
if (words[j].trim().length() == 0)
{
continue;
}
float wWidth = font.getStringWidth(words[j]) / 1000f * 9f;
float totalWidth = widthCount + wWidth + spaceWidth;
if (totalWidth < width + spaceWidth)
{
sb.append(words[j]);
sb.append(" ");
widthCount = totalWidth;
}
else
{
result.add(sb.toString().trim());
sb = new StringBuilder();
sb.append(words[j]);
sb.append(" ");
widthCount = totalWidth - widthCount;
}
}
result.add(sb.toString().trim());
}
return result;
}
//
// helper classes
//
static class Chunk
{
Chunk(float x, float y, int space, PDFont font, String text)
{
this.x = x;
this.y = y;
this.space = space;
this.font = font;
this.text = text;
}
final float x, y;
final int space;
final PDFont font;
final String text;
}
//
// members
//
private final PDDocument doc;
private final PDJpeg logoImg;
private final String[] header;
private PDPageContentStream content = null;
private float previousBandBase = 0;
}
PDDocument document = new PDDocument();
PdfRenderingEndorsementAlternative renderer = new PdfRenderingEndorsementAlternative(document, logoStream, header);
renderer.render(
new BandColumn(leftHalfPageField, "Nombre del contrato/asegurado:", "Prueba Jesus Fac No Prop"),
new BandColumn(rightHalfPageField, "Nombre del contrato/asegurado:", "Prueba Jesus Fac No Prop con Endoso")
);
renderer.gap(20);
renderer.render(
new BandColumn(leftHalfPageField, "País:", "México"),
new BandColumn(rightHalfPageField, "País:", "México")
);
renderer.close();
document.save(new File(RESULT_FOLDER, "Endorsement.pdf"));