diff --git a/pdf-2/pom.xml b/pdf-2/pom.xml index 2079ff70e5..430cacbfca 100644 --- a/pdf-2/pom.xml +++ b/pdf-2/pom.xml @@ -35,6 +35,21 @@ pdfbox ${pdfbox.version} + + org.apache.poi + poi-ooxml + ${poi-ooxml.version} + + + org.apache.logging.log4j + log4j-api + ${log4j-api.version} + + + org.apache.logging.log4j + log4j-core + ${log4j-core.version} + @@ -52,6 +67,9 @@ 7.2.3 3.0.1 3.0.0 + 5.2.5 + 2.20.0 + 2.20.0 \ No newline at end of file diff --git a/pdf-2/src/main/java/com/baeldung/exceltopdf/ExcelToPDFConverter.java b/pdf-2/src/main/java/com/baeldung/exceltopdf/ExcelToPDFConverter.java new file mode 100644 index 0000000000..97d7b36bd6 --- /dev/null +++ b/pdf-2/src/main/java/com/baeldung/exceltopdf/ExcelToPDFConverter.java @@ -0,0 +1,242 @@ +package com.baeldung.exceltopdf; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.math.BigDecimal; +import java.util.Iterator; + +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.IndexedColors; +import org.apache.poi.ss.usermodel.VerticalAlignment; +import org.apache.poi.xssf.usermodel.XSSFColor; +import org.apache.poi.xssf.usermodel.XSSFFont; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Cell; + +import com.itextpdf.text.BaseColor; +import com.itextpdf.text.Document; +import com.itextpdf.text.DocumentException; +import com.itextpdf.text.Element; +import com.itextpdf.text.Font; +import com.itextpdf.text.FontFactory; +import com.itextpdf.text.Paragraph; +import com.itextpdf.text.Phrase; +import com.itextpdf.text.pdf.PdfPCell; +import com.itextpdf.text.pdf.PdfPTable; +import com.itextpdf.text.pdf.PdfWriter; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class ExcelToPDFConverter { + + private static final Logger logger = LogManager.getLogger(ExcelToPDFConverter.class); + + public static XSSFWorkbook readExcelFile(String excelFilePath) throws IOException { + FileInputStream inputStream = new FileInputStream(excelFilePath); + XSSFWorkbook workbook = new XSSFWorkbook(inputStream); + inputStream.close(); + return workbook; + } + + private static Document createPDFDocument(String pdfFilePath) throws IOException, DocumentException { + Document document = new Document(); + PdfWriter.getInstance(document, new FileOutputStream(pdfFilePath)); + document.open(); + return document; + } + + public static void convertExcelToPDF(String excelFilePath, String pdfFilePath) throws IOException, DocumentException { + XSSFWorkbook workbook = readExcelFile(excelFilePath); + Document document = createPDFDocument(pdfFilePath); + + for (int i = 0; i < workbook.getNumberOfSheets(); i++) { + XSSFSheet worksheet = workbook.getSheetAt(i); + + // Add header with sheet name as title + Paragraph title = new Paragraph(worksheet.getSheetName(), new Font(Font.FontFamily.HELVETICA, 18, Font.BOLD)); + title.setSpacingAfter(20f); + title.setAlignment(Element.ALIGN_CENTER); + document.add(title); + + createAndAddTable(worksheet, document); + // Add a new page for each sheet (except the last one) + if (i < workbook.getNumberOfSheets() - 1) { + document.newPage(); + } + } + + document.close(); + workbook.close(); + } + + private static void createAndAddTable(XSSFSheet worksheet, Document document) throws DocumentException, IOException { + PdfPTable table = new PdfPTable(worksheet.getRow(0) + .getPhysicalNumberOfCells()); + table.setWidthPercentage(100); + addTableHeader(worksheet, table); + addTableData(worksheet, table); + document.add(table); + } + + private static void addTableHeader(XSSFSheet worksheet, PdfPTable table) throws DocumentException, IOException { + Row headerRow = worksheet.getRow(0); + for (int i = 0; i < headerRow.getPhysicalNumberOfCells(); i++) { + Cell cell = headerRow.getCell(i); + String headerText = getCellText(cell); + PdfPCell headerCell = new PdfPCell(new Phrase(headerText, getCellStyle(cell))); + setBackgroundColor(cell, headerCell); + setCellAlignment(cell, headerCell); + table.addCell(headerCell); + } + } + + public static String getCellText(Cell cell) { + String cellValue; + switch (cell.getCellType()) { + case STRING: + cellValue = cell.getStringCellValue(); + break; + case NUMERIC: + cellValue = String.valueOf(BigDecimal.valueOf(cell.getNumericCellValue())); + break; + case BLANK: + default: + cellValue = ""; + break; + } + return cellValue; + } + + private static void addTableData(XSSFSheet worksheet, PdfPTable table) throws DocumentException, IOException { + Iterator rowIterator = worksheet.iterator(); + while (rowIterator.hasNext()) { + Row row = rowIterator.next(); + if (row.getRowNum() == 0) { + continue; + } + for (int i = 0; i < row.getPhysicalNumberOfCells(); i++) { + Cell cell = row.getCell(i); + String cellValue = getCellText(cell); + PdfPCell cellPdf = new PdfPCell(new Phrase(cellValue, getCellStyle(cell))); + setBackgroundColor(cell, cellPdf); + setCellAlignment(cell, cellPdf); + table.addCell(cellPdf); + } + } + } + + private static void setBackgroundColor(Cell cell, PdfPCell cellPdf) { + // Set background color + short bgColorIndex = cell.getCellStyle() + .getFillForegroundColor(); + if (bgColorIndex != IndexedColors.AUTOMATIC.getIndex()) { + XSSFColor bgColor = (XSSFColor) cell.getCellStyle() + .getFillForegroundColorColor(); + if (bgColor != null) { + byte[] rgb = bgColor.getRGB(); + if (rgb != null && rgb.length == 3) { + cellPdf.setBackgroundColor(new BaseColor(rgb[0] & 0xFF, rgb[1] & 0xFF, rgb[2] & 0xFF)); + } + } + } + } + + private static void setCellAlignment(Cell cell, PdfPCell cellPdf) { + CellStyle cellStyle = cell.getCellStyle(); + + HorizontalAlignment horizontalAlignment = cellStyle.getAlignment(); + VerticalAlignment verticalAlignment = cellStyle.getVerticalAlignment(); + + switch (horizontalAlignment) { + case LEFT: + cellPdf.setHorizontalAlignment(Element.ALIGN_LEFT); + break; + case CENTER: + cellPdf.setHorizontalAlignment(Element.ALIGN_CENTER); + break; + case JUSTIFY: + case FILL: + cellPdf.setVerticalAlignment(Element.ALIGN_JUSTIFIED); + break; + case RIGHT: + cellPdf.setHorizontalAlignment(Element.ALIGN_RIGHT); + break; + } + + switch (verticalAlignment) { + case TOP: + cellPdf.setVerticalAlignment(Element.ALIGN_TOP); + break; + case CENTER: + cellPdf.setVerticalAlignment(Element.ALIGN_MIDDLE); + break; + case JUSTIFY: + cellPdf.setVerticalAlignment(Element.ALIGN_JUSTIFIED); + break; + case BOTTOM: + cellPdf.setVerticalAlignment(Element.ALIGN_BOTTOM); + break; + } + } + + private static Font getCellStyle(Cell cell) throws DocumentException, IOException { + Font font = new Font(); + CellStyle cellStyle = cell.getCellStyle(); + org.apache.poi.ss.usermodel.Font cellFont = cell.getSheet() + .getWorkbook() + .getFontAt(cellStyle.getFontIndexAsInt()); + + short fontColorIndex = cellFont.getColor(); + if (fontColorIndex != IndexedColors.AUTOMATIC.getIndex() && cellFont instanceof XSSFFont) { + XSSFColor fontColor = ((XSSFFont) cellFont).getXSSFColor(); + if (fontColor != null) { + byte[] rgb = fontColor.getRGB(); + if (rgb != null && rgb.length == 3) { + font.setColor(new BaseColor(rgb[0] & 0xFF, rgb[1] & 0xFF, rgb[2] & 0xFF)); + } + } + } + + if (cellFont.getItalic()) { + font.setStyle(Font.ITALIC); + } + + if (cellFont.getStrikeout()) { + font.setStyle(Font.STRIKETHRU); + } + + if (cellFont.getUnderline() == 1) { + font.setStyle(Font.UNDERLINE); + } + + short fontSize = cellFont.getFontHeightInPoints(); + font.setSize(fontSize); + + if (cellFont.getBold()) { + font.setStyle(Font.BOLD); + } + + String fontName = cellFont.getFontName(); + if (FontFactory.isRegistered(fontName)) { + font.setFamily(fontName); // Use extracted font family if supported by iText + } else { + logger.warn("Unsupported font type: {}", fontName); + // - Use a fallback font (e.g., Helvetica) + font.setFamily("Helvetica"); + } + + return font; + } + + public static void main(String[] args) throws DocumentException, IOException { + String excelFilePath = "src/main/resources/excelsample.xlsx"; + String pdfFilePath = "src/main/resources/pdfsample.pdf"; + convertExcelToPDF(excelFilePath, pdfFilePath); + } +} diff --git a/pdf-2/src/main/resources/excelsample.xlsx b/pdf-2/src/main/resources/excelsample.xlsx new file mode 100644 index 0000000000..771d312ae0 Binary files /dev/null and b/pdf-2/src/main/resources/excelsample.xlsx differ diff --git a/pdf-2/src/main/resources/pdfsample.pdf b/pdf-2/src/main/resources/pdfsample.pdf new file mode 100644 index 0000000000..6a47504513 --- /dev/null +++ b/pdf-2/src/main/resources/pdfsample.pdf @@ -0,0 +1,43 @@ +%PDF-1.4 +% +3 0 obj +<>stream +xWR0+.Pu@R ti c0d:}%K&adasёtdӦjnVX, BG?z=>U{kTqy hepj3'BL9.@]b}s-<Bi&bHX}CiT.ٳ5 wF4?KѼɖ$gW&I$hDq 'GJ(B$ +HojGȯ]I$hDIM-DI&I$Q\$M4I"$b`fyShDI&I;uH_ `-aK;h1zU^3\5+:r9stb!i9܅dݪFV,F"T`|{ųjcŗZfJl]^5a#lVO<_N9q~Xv6āE* X!Ĭ)u^3O3l_r p@8u \%/'4Ee +(T`w3|Y}*vOҖQ$=F̐ 9d(z?)VmD.ER{|'Uf*/(^;Qf⛥DaOHK{PWok=mBժf=]^dbxd]9L7gNkrj`$y>W7th)˳~>o};7\Li*hT +endstream +endobj +5 0 obj +<>>>/Contents 3 0 R/Parent 4 0 R>> +endobj +1 0 obj +<> +endobj +2 0 obj +<> +endobj +4 0 obj +<> +endobj +6 0 obj +<> +endobj +7 0 obj +<> +endobj +xref +0 8 +0000000000 65535 f +0000000954 00000 n +0000001047 00000 n +0000000015 00000 n +0000001135 00000 n +0000000833 00000 n +0000001186 00000 n +0000001231 00000 n +trailer +<<6a28b1036b62f3808f3bfb62a88a5239>]>> +%iText-5.5.13.3 +startxref +1391 +%%EOF