GroupDocs.Assembly for Java seamlessly integrates with JDBC, allowing you to generate documents directly from database queries. You can wrap a java.sql.ResultSet into a DataTable, or combine several tables into a DataSet, making it easy to create reports from MySQL, PostgreSQL, SQL Server, Oracle, SQLite, and other databases. Any JDBC driver can be used.
Here are the steps to generate documents from databases:
Connect to your database using JDBC
Execute SQL queries and populate DataSet or DataTable
Create a template document with expression tags referencing table and column names
Use DocumentAssembler to assemble the template with database data
Save the assembled document
Note
GroupDocs.Assembly supports DataSet, DataTable, and DataRow objects from the com.groupdocs.assembly.system.data package as data sources. A DataTable reads all rows of the ResultSet when it is created, so the database connection can be closed before the document is assembled.
Generate Document from DataTable
The simplest approach is to use a DataTable:
importcom.groupdocs.assembly.*;importcom.groupdocs.assembly.system.data.*;importjava.sql.*;publicstaticvoidgenerateFromDataTable()throwsException{// Connect to database and populate DataTable
// Any JDBC URL works, e.g. "jdbc:mysql://localhost:3306/MyDB" (the JDBC driver must be on the classpath)
StringconnectionString="jdbc:sqlite:MyDB.db";Stringquery="SELECT CustomerName, Email, Balance FROM Customers";DataTablecustomersTable;try(Connectionconnection=DriverManager.getConnection(connectionString);Statementstatement=connection.createStatement();ResultSetresultSet=statement.executeQuery(query)){customersTable=newDataTable(resultSet,"Customers");}// Assemble document
DocumentAssemblerassembler=newDocumentAssembler();assembler.assembleDocument("Template.docx","Output.docx",newDataSourceInfo(customersTable,"customers"));System.out.println("Document generated from DataTable successfully.");}
Numeric format strings follow the Java DecimalFormat pattern syntax (for example, "$#,##0.00"); .NET standard format strings such as "C" are not supported. Decimal and grouping separators depend on the default locale of the JVM.
Generate Document from DataSet
When working with multiple tables, use DataSet:
importcom.groupdocs.assembly.*;importcom.groupdocs.assembly.system.data.*;importjava.sql.*;publicstaticvoidgenerateFromDataSet()throwsException{StringconnectionString="jdbc:sqlite:MyDB.db";DataSetdataSet=newDataSet();try(Connectionconnection=DriverManager.getConnection(connectionString);Statementstatement=connection.createStatement()){// Load customers table
try(ResultSetresultSet=statement.executeQuery("SELECT * FROM Customers")){dataSet.getTables().add(newDataTable(resultSet,"Customers"));}// Load orders table
try(ResultSetresultSet=statement.executeQuery("SELECT * FROM Orders")){dataSet.getTables().add(newDataTable(resultSet,"Orders"));}}DocumentAssemblerassembler=newDocumentAssembler();assembler.assembleDocument("Template.docx","Output.docx",newDataSourceInfo(dataSet,"ds"));System.out.println("Document generated from DataSet successfully.");}
Instead of querying tables one by one, you can pass a JDBC Connection to the DataSet constructor. It loads all tables of the database (or of the specified schema) together with their primary keys and the relations defined by foreign keys:
importcom.groupdocs.assembly.*;importcom.groupdocs.assembly.system.data.*;importjava.sql.*;publicstaticvoidgenerateFromConnection()throwsException{StringconnectionString="jdbc:sqlite:MyDB.db";DataSetdataSet;try(Connectionconnection=DriverManager.getConnection(connectionString)){dataSet=newDataSet(connection);// Or, to load tables of a specific schema:
// dataSet = new DataSet(connection, "PUBLIC");
}DocumentAssemblerassembler=newDocumentAssembler();assembler.assembleDocument("Template.docx","Output.docx",newDataSourceInfo(dataSet,"ds"));System.out.println("Document generated from the database successfully.");}
Filtering and Sorting Data
You can filter and sort data in the SQL query before assembly:
importcom.groupdocs.assembly.*;importcom.groupdocs.assembly.system.data.*;importjava.sql.*;publicstaticvoidgenerateFromFilteredData()throwsException{StringconnectionString="jdbc:sqlite:MyDB.db";DataTablecustomersTable;try(Connectionconnection=DriverManager.getConnection(connectionString);PreparedStatementstatement=connection.prepareStatement("SELECT * FROM Customers WHERE Balance > ? ORDER BY CustomerName ASC")){statement.setDouble(1,1000);try(ResultSetresultSet=statement.executeQuery()){customersTable=newDataTable(resultSet,"Customers");}}DocumentAssemblerassembler=newDocumentAssembler();assembler.assembleDocument("Template.docx","Output.docx",newDataSourceInfo(customersTable,"customers"));System.out.println("Document generated from filtered data successfully.");}
Working with Related Tables
DataSet supports data relations for master-detail reports:
importcom.groupdocs.assembly.*;importcom.groupdocs.assembly.system.data.*;importjava.sql.*;publicstaticvoidgenerateWithRelations()throwsException{StringconnectionString="jdbc:sqlite:MyDB.db";DataSetdataSet=newDataSet();try(Connectionconnection=DriverManager.getConnection(connectionString);Statementstatement=connection.createStatement()){try(ResultSetresultSet=statement.executeQuery("SELECT * FROM Customers")){dataSet.getTables().add(newDataTable(resultSet,"Customers"));}try(ResultSetresultSet=statement.executeQuery("SELECT * FROM Orders")){dataSet.getTables().add(newDataTable(resultSet,"Orders"));}}// Create relation
DataRelationrelation=newDataRelation("CustomerOrders",dataSet.getTables().get("Customers").getColumns().get("CustomerId"),dataSet.getTables().get("Orders").getColumns().get("CustomerId"));dataSet.getRelations().add(relation);DocumentAssemblerassembler=newDocumentAssembler();assembler.assembleDocument("Template.docx","Output.docx",newDataSourceInfo(dataSet.getTables().get("Customers"),"customers"));System.out.println("Document generated with relations successfully.");}
Template with relations (child rows are accessed by the name of the child table):
When using database connections, always ensure proper disposal of resources. Use try-with-resources statements or try-finally blocks to close connections, statements, and result sets.
Advanced Usage Topics
To learn more about working with complex database queries, stored procedures, parameterized queries, and performance optimization for large datasets, please refer to the advanced usage section.
More resources
GitHub Examples
You may easily run the code above and see the feature in action in our GitHub examples: