Closed ghost closed 3 years ago
Hi @gabu99,
there is no easy switch to turn this off as of now. But I think it should not be too hard to implement a custom cell type that just breaks without adding hyphens.
I will have a look.
Best, Stefan
Hey @vandeseer
Thank you very much, I appreciate.
I hacked around a bit found a solution using a custom cell type and the very nice library https://github.com/davidmoten/word-wrap. You would need to include that library in your pom.xml
:
<dependency>
<groupId>com.github.davidmoten</groupId>
<artifactId>word-wrap</artifactId>
<version>0.1.8</version>
</dependency>
The full example now looks like this:
import lombok.experimental.SuperBuilder;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.davidmoten.text.utils.WordWrap;
import org.vandeseer.easytable.TableDrawer;
import org.vandeseer.easytable.drawing.Drawer;
import org.vandeseer.easytable.drawing.cell.TextCellDrawer;
import org.vandeseer.easytable.structure.Row;
import org.vandeseer.easytable.structure.Table;
import org.vandeseer.easytable.structure.cell.TextCell;
import org.vandeseer.easytable.util.PdfUtil;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
public class EasytableCustomMain {
@SuperBuilder
private static class MyCustomCell extends TextCell {
private List<String> lines;
public List<String> getLines() {
if (lines != null) {
return lines;
}
return Arrays.stream(
WordWrap
.from(getText()).maxWidth(getMaxWidthOfText() - getHorizontalPadding())
.stringWidth(charSequence -> PdfUtil.getStringWidth(charSequence.toString(), getFont(), getFontSize()))
.breakWords(true)
.insertHyphens(false)
.wrap().split("\n")
)
.collect(Collectors.toList());
}
@Override
public float getWidthOfText() {
return lines.stream()
.map(line -> PdfUtil.getStringWidth(line, getFont(), getFontSize()))
.max(Comparator.naturalOrder())
.orElse(PdfUtil.getStringWidth(getText(), getFont(), getFontSize()));
}
@Override
public float getTextHeight() {
if (this.textHeight != null) {
return this.textHeight;
}
this.textHeight = PdfUtil.getFontHeight(getFont(), getFontSize());
final float heightOfTextLines = getLines().size() * this.textHeight;
final float heightOfLineSpacing = (getLines().size() - 1) * this.textHeight * getLineSpacing();
this.textHeight = heightOfTextLines + heightOfLineSpacing;
return this.textHeight;
}
@Override
public Drawer getDrawer() {
return new TextCellDrawer<MyCustomCell>(this) {
@Override
protected List<String> calculateAndGetLines(PDFont currentFont, int currentFontSize, float maxWidth) {
return ((MyCustomCell) cell).getLines();
}
};
}
}
public static void main(String[] args) throws Exception {
try (PDDocument document = new PDDocument()) {
final PDPage page = new PDPage(PDRectangle.A4);
document.addPage(page);
try (PDPageContentStream contentStream = new PDPageContentStream(document, page)) {
// Build the table
Table myTable = Table.builder()
.addColumnsOfWidth(200, 200)
.padding(2)
.addRow(Row.builder()
.add(MyCustomCell.builder().text("This is a very long text that should be split").build())
.add(MyCustomCell.builder().text("Fubarfubarfubarfubarfubarfubarfubarfubarfubarbazzz").build())
.build())
.addRow(Row.builder()
.add(MyCustomCell.builder().text("Two One").build())
.add(MyCustomCell.builder().text("Two Two").build())
.build())
.build();
// Set up the drawer
TableDrawer tableDrawer = TableDrawer.builder()
.contentStream(contentStream)
.startX(20f)
.startY(page.getMediaBox().getUpperRightY() - 20f)
.table(myTable)
.build();
// And go for it!
tableDrawer.draw();
}
document.save("example.pdf");
}
}
}
Please also note that you will need Lombok for that, too:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
</dependency>
Let me know if that works for you.
Best, Stefan
Thank you for your quick support.
Unfortunately, when I try to use the code there seem to be problems with extending the TextCell class.
The first error says Implicit super constructor TextCell() is undefined for default constructor. Must define an explicit constructor
.
And getMaxWidthOfText seems to be a private method, such that I can't call it in this class.
Do you have any ideas how to solve the problem?
Thank you again!
Hey @gabu99,
sorry, my fault: You need to get version 0.8.0 of easytable (which I just published with the changes necessary).
Regarding the Implicit super constructor
issue: It may stem from not using any Lombok support in Eclipse. I don't use Eclipse myself but maybe this link is of use.
Also you can try to run the code from the command line. It should compile correctly then, because the Lombok stuff is done automatically (it's just your IDE not "understanding" it as of now).
Best, Stefan
@vandeseer Unfortunately, the code still did not work after updating the version of easytable (same errors). Thank you for your efforts though. If I find a solution, I'll post it.
Hey @gabu99,
I am pretty confident we get this running. So please don't give up! 😉
Did it work running from the command line? Were you able to get the Lombok plugin installed?
Can you share an example of your code which has the problem?
Hi @vandeseer I had the same problem too. I was able to hide the line-break hyphen by modifying this issue as a reference. thank you! easytable version: 0.8.5 IDE: Eclipse+Java8 I post the code in case it helps someone.
@SuperBuilder
private static class MyCustomCell extends TextCell {
private List<String> lines;
public List<String> getLines() {
if (lines != null) {
return lines;
}
return Arrays.stream(
WordWrap
.from(getText()).maxWidth(getMaxWidth())
.stringWidth(charSequence -> PdfUtil.getStringWidth(charSequence.toString(), getFont(), getFontSize()))
.breakWords(true)
.insertHyphens(false)
.wrap().split("\n")
)
.collect(Collectors.toList());
}
@Override
public float getWidthOfText() {
return lines.stream()
.map(line -> PdfUtil.getStringWidth(line, getFont(), getFontSize()))
.max(Comparator.naturalOrder())
.orElse(PdfUtil.getStringWidth(getText(), getFont(), getFontSize()));
}
@Override
public float getTextHeight() {
/*if (this.textHeight != null) {
return this.textHeight;
}*/
Float textHeight = PdfUtil.getFontHeight(getFont(), getFontSize());
final float heightOfTextLines = getLines().size() * textHeight;
final float heightOfLineSpacing = (getLines().size() - 1) * textHeight * getLineSpacing();
textHeight = heightOfTextLines + heightOfLineSpacing;
return textHeight;
}
@Override
public Drawer getDrawer() {
return new TextCellDrawer<MyCustomCell>(this) {
@Override
protected List<String> calculateAndGetLines(PDFont currentFont, int currentFontSize, float maxWidth) {
return ((MyCustomCell) cell).getLines();
}
};
}
}
Hi, I am currently working on a table that contains information about IT projects. As I use Japanese for some parts, words can get quite long, such that line breaks become necessary. Now I was wondering if it is possible to disable hyphens at the end of the line where words get too long. Thank you very much in advance.