-
-
Notifications
You must be signed in to change notification settings - Fork 156
Boxable is a Java library that simplifies the creation of tables in PDF documents. It's built on top of Apache PDFBox and provides a high-level API for creating professional tables with rich formatting.
Boxable requires Java 8 or higher. The library is compiled with Java 17 but is compatible with Java 8+.
Yes! Boxable is actively maintained and used in production applications. Version 1.8.2 is the current stable release.
Maven:
<dependency>
<groupId>com.github.dhorions</groupId>
<artifactId>boxable</artifactId>
<version>1.8.2</version>
</dependency>Gradle:
implementation 'com.github.dhorions:boxable:1.8.2'Boxable depends on:
- Apache PDFBox 3.0.6
- Apache Commons CSV (for CSV import)
- JSoup (for HTML parsing)
These are automatically included when you add Boxable to your project.
See the Getting Started guide or Tutorial 01 for a complete example.
Make sure you call table.draw() before saving the document:
table.draw(); // Don't forget this!
document.save("output.pdf");The table width is specified when creating the BaseTable:
float tableWidth = page.getMediaBox().getWidth() - (2 * margin);
BaseTable table = new BaseTable(yStart, yStartNewPage, bottomMargin,
tableWidth, margin, document, page,
true, true);Yes! Set drawLines to false when creating the table:
BaseTable table = new BaseTable(yStart, yStartNewPage, bottomMargin,
tableWidth, margin, document, page,
false, true); // false = no bordersYou can also set setOuterBorderStyle() for custom border control.
Use setFillColor() for background and setTextColor() for text:
Cell<PDPage> cell = row.createCell(50, "Content");
cell.setFillColor(Color.BLUE);
cell.setTextColor(Color.WHITE);Yes! Boxable supports many HTML tags including <b>, <i>, <u>, <s>, <br/>, <sup>, <sub>, lists, and more. See HTML Tags Reference for details.
Use createImageCell():
BufferedImage bufferedImage = ImageIO.read(new File("image.png"));
Image image = new Image(bufferedImage);
ImageCell<PDPage> cell = row.createImageCell(50, image);See Tutorial 05: Images for examples.
Use setTextRotated(true):
Cell<PDPage> cell = row.createCell(10, "VERTICAL");
cell.setTextRotated(true);Yes:
cell.setFontSize(14f);Yes! When a table reaches the bottom margin, Boxable automatically creates a new page and continues the table.
Use addHeaderRow():
Row<PDPage> headerRow = table.createRow(20f);
// ... create header cells ...
table.addHeaderRow(headerRow);Headers added this way automatically repeat on each new page.
Yes! Call addHeaderRow() multiple times:
table.addHeaderRow(headerRow1);
table.addHeaderRow(headerRow2);
table.addHeaderRow(headerRow3);Use the DataTable class:
String csvData = "Name;Age\\nJohn;30\\nJane;25";
BaseTable baseTable = new BaseTable(...);
DataTable dataTable = new DataTable(baseTable, page);
dataTable.addCsvToTable(csvData, DataTable.HASHEADER, ';');
baseTable.draw();Yes:
List<List> data = new ArrayList<>();
data.add(new ArrayList<>(Arrays.asList("Name", "Age")));
data.add(new ArrayList<>(Arrays.asList("John", "30")));
DataTable dataTable = new DataTable(baseTable, page);
dataTable.addListToTable(data, DataTable.HASHEADER);Pass a list of relative widths:
DataTable dataTable = new DataTable(baseTable, page,
Arrays.asList(3f, 1f, 1f, 1f));
// First column is 3x wider than othersBoxable handles large tables efficiently. For best performance:
- Use
drawContent = trueanddrawLines = trueonly when needed - Consider breaking very large tables into multiple tables
- See Tutorial 09: Multi-Page Tables
Boxable is designed to be memory-efficient. It processes rows as they're added rather than storing everything in memory.
Yes! Use HTML <table> tags within cell content:
String nestedTable = "<table>" +
"<tr><td>Name</td><td>Value</td></tr>" +
"<tr><td>Item 1</td><td>100</td></tr>" +
"</table>";
Cell<PDPage> cell = row.createCell(50, nestedTable);See Tutorial 10: Nested Tables.
Fixed-height rows automatically shrink text to fit a specified height:
Row<PDPage> row = table.createRow(12f);
row.setFixedHeight(true); // Text will shrink to fit 12pt heightSee Tutorial 11: Fixed Height Rows.
Yes, in nested tables using colspan:
"<table>
<tr><td colspan='3'>Spans 3 columns</td></tr>
<tr><td>Col1</td><td>Col2</td><td>Col3</td></tr>
</table>"Possible solutions:
- Increase row height
- Use fixed-height rows with auto-shrink
- Add line breaks with
<br/>tags - Reduce font size
Make sure you set both drawLines and drawContent to true:
BaseTable table = new BaseTable(yStart, yStartNewPage, bottomMargin,
tableWidth, margin, document, page,
true, true); // both trueThe default font (Helvetica) doesn't support all Unicode characters. Use:
- Standard ASCII characters
- HTML entity references
- Or load a custom font that supports your characters
Make sure your yStart calculation accounts for margins:
float yStart = page.getMediaBox().getHeight() - margin;Run the built-in tutorials:
mvn test -Dtest=TutorialRunnerThis generates 12 PDF examples covering all features.
Report issues on GitHub: https://github.com/dhorions/boxable/issues
Contributions are welcome! See issue #41 for documentation needs.
Boxable is open source. For commercial support inquiries, contact the maintainers through GitHub.
Special thanks to :
=======
Copyright 2026
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.