// Create a new workbook Workbook workbook = new Workbook(); //Load template file from resource InputStream templateFile = this.getResourceStream("xlsx/Template_SalesDataGroup.xlsx"); workbook.open(templateFile); //#region Define custom classes //public class SalesData //{ // public List sales; //} //public class SalesRecord //{ // public String area; // public String city; // public String category; // public String name; // public double revenue; //} //#endregion SalesData datasource = new SalesData(); datasource.sales = new ArrayList(); //#region Init Data System.out.println("Creating test data."); String[] areas = new String[]{"North America", "South America"}; String[] cities = new String[]{"Chicago", "New York", "Santiago", "Quito", "Fremont", "Buenos Aires", "Medillin", "Minnesota"}; String[] categories = new String[]{"Consumer Electronics", "Mobile"}; String[] category1NamePrefixes = new String[]{"Bose ", "Canon ", "Haier ", "IFB ", "Mi ", "Sennheiser "}; String[] category2NamePrefixes = new String[]{"iPhone ", "OnePlus ", "Redmi ", "Samsung "}; Random rand = new Random(); // You can increase the loop count if the demo is too fast on your computer. for (int i = 0; i < 30000; i++) { SalesRecord item = new SalesRecord(); item.area = areas[rand.nextInt(areas.length)]; item.city = cities[rand.nextInt(cities.length)]; int categoryId = rand.nextInt(categories.length); item.category = categories[categoryId]; String[] names = (categoryId == 0) ? category1NamePrefixes : category2NamePrefixes; item.name = names[rand.nextInt(names.length)] + (10 + rand.nextInt(10000 - 10)); item.revenue = 10000 + rand.nextInt(100000 - 10000); datasource.sales.add(item); } //#endregion //Init template global settings workbook.getNames().add("TemplateOptions.KeepLineSize", "true"); //Add data source workbook.addDataSource("ds", datasource); // Cancel when cancel key pressed or timeout reached. try (CancellationTokenSource cancellation = new CancellationTokenSource()) { // Important: why we've commented-out some code here: // To handle the cancel key event of the console, we are using `sun.misc.Signal` in this sample. // However, the classes of `sun.misc` might be unavailable in your JDK, because they are restricted APIs. // You need to either use `jdk.internal.misc.*` (Java 9+) or use // 3rd-party components (such as `javax.realtime.POSIXSignalHandler`) to handle // the console cancel key event if `sum.misc` is unavailable. // final sun.misc.SignalHandler[] oldSignal = new sun.misc.SignalHandler[1]; // sun.misc.SignalHandler cancelHandler = sig -> { // // Exit process gracefully // cancellation.cancel(); // // Invoke rest of the handlers of Console.CancelKeyPress // if (oldSignal[0] != null) { // oldSignal[0].handle(sig); // } // }; // sun.misc.Signal cancelKeyPressSignal = new sun.misc.Signal("INT"); // oldSignal[0] = sun.misc.Signal.handle(cancelKeyPressSignal, cancelHandler); cancellation.cancelAfter(Duration.ofSeconds(10)); System.out.println("Start ProcessTemplate."); try { workbook.processTemplate(cancellation.getToken()); System.out.println("ProcessTemplate finished."); } catch (java.util.concurrent.CancellationException ex) { System.out.println("ProcessTemplate was canceled."); } // sun.misc.Signal.handle(cancelKeyPressSignal, oldSignal[0]); } catch (Exception e) { throw new RuntimeException(e); }