簡體   English   中英

Java Apache POI Excel 另存為 PDF

[英]Java Apache POI Excel save as PDF

如何將excel文件轉換/保存為pdf 我正在使用java play framework生成一些excel文件,現在要求更改為pdf 我不想重新編碼一切。

有沒有辦法轉換成pdf

我生成的excel文件來自模板; 我閱讀了 excel 模板文件,寫入了更改,然后另存為新的 excel 文件。 這樣,模板不變。 它包含邊框、圖像和其他格式。

您需要以下 Java 庫和關聯的 JAR 文件才能使程序運行。 興趣點 v3.8 iText v5.3.4

試試這個例子將 XLS 轉換為 PDF

下面提供了接受 Excel 電子表格數據作為輸入並將其轉換為 PDF 表格數據的完整 Java 代碼:

 import java.io.FileInputStream;
    import java.io.*;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    import org.apache.poi.hssf.usermodel.HSSFSheet;
    import org.apache.poi.ss.usermodel.*;
    import java.util.Iterator;
   import com.itextpdf.text.*;
    import com.itextpdf.text.pdf.*;

    public class excel2pdf {  
            public static void main(String[] args) throws Exception{

                    FileInputStream input_document = new FileInputStream(new File("C:\\excel_to_pdf.xls"));
                    // Read workbook into HSSFWorkbook
                    HSSFWorkbook my_xls_workbook = new HSSFWorkbook(input_document); 
                    // Read worksheet into HSSFSheet
                    HSSFSheet my_worksheet = my_xls_workbook.getSheetAt(0); 
                    // To iterate over the rows
                    Iterator<Row> rowIterator = my_worksheet.iterator();
                    //We will create output PDF document objects at this point
                    Document iText_xls_2_pdf = new Document();
                    PdfWriter.getInstance(iText_xls_2_pdf, new FileOutputStream("Excel2PDF_Output.pdf"));
                    iText_xls_2_pdf.open();
                    //we have two columns in the Excel sheet, so we create a PDF table with two columns
                    //Note: There are ways to make this dynamic in nature, if you want to.
                    PdfPTable my_table = new PdfPTable(2);
                    //We will use the object below to dynamically add new data to the table
                    PdfPCell table_cell;
                    //Loop through rows.
                    while(rowIterator.hasNext()) {
                            Row row = rowIterator.next(); 
                            Iterator<Cell> cellIterator = row.cellIterator();
                                    while(cellIterator.hasNext()) {
                                            Cell cell = cellIterator.next(); //Fetch CELL
                                            switch(cell.getCellType()) { //Identify CELL type
                                                    //you need to add more code here based on
                                                    //your requirement / transformations
                                            case Cell.CELL_TYPE_STRING:
                                                    //Push the data from Excel to PDF Cell
                                                     table_cell=new PdfPCell(new Phrase(cell.getStringCellValue()));
                                                     //feel free to move the code below to suit to your needs
                                                     my_table.addCell(table_cell);
                                                    break;
                                            }
                                            //next line
                                    }

                    }
                    //Finally add the table to PDF document
                    iText_xls_2_pdf.add(my_table);                       
                    iText_xls_2_pdf.close();                
                    //we created our pdf file..
                    input_document.close(); //close xls
            }
    }

我希望這能幫到您

添加到 assylias 的答案

上面來自 assylias 的代碼對我解決這個問題非常有幫助。 如果您不關心生成的 PDF 看起來與您的 excel pdf 導出看起來完全一樣,那么來自 santhosh 的答案可能會很棒。 但是,如果您使用 Apache POI 填寫 excel 模板,然后嘗試導出該模板,同時保留其外觀,而不是在 iText 中編寫大量代碼只是為了接近該外觀,那么 VBS 選項是相當不錯。

我將分享上面的 kotlin assylias 的 Java 版本,以幫助任何人。 所有解決方案的一般形式都歸功於 assylias。

在 Java 中:

try {
    //create a temporary file and grab the path for it
    Path tempScript = Files.createTempFile("script", ".vbs");

    //read all the lines of the .vbs script into memory as a list
    //here we pull from the resources of a Gradle build, where the vbs script is stored
    System.out.println("Path for vbs script is: '" + Main.class.getResource("xl2pdf.vbs").toString().substring(6) + "'");
    List<String> script = Files.readAllLines(Paths.get(Main.class.getResource("xl2pdf.vbs").toString().substring(6)));

    // append test.xlsm for file name. savePath was passed to this function
    String templateFile = savePath + "\\test.xlsm";
    templateFile = templateFile.replace("\\", "\\\\");
    String pdfFile = savePath + "\\test.pdf";
    pdfFile = pdfFile.replace("\\", "\\\\");
    System.out.println("templateFile is: " + templateFile);
    System.out.println("pdfFile is: " + pdfFile);

    //replace the placeholders in the vbs script with the chosen file paths
    for (int i = 0; i < script.size(); i++) {
        script.set(i, script.get(i).replaceAll("XL_FILE", templateFile));
        script.set(i, script.get(i).replaceAll("PDF_FILE", pdfFile));
        System.out.println("Line " + i + " is: " + script.get(i));
    }

    //write the modified code to the temporary script
    Files.write(tempScript, script);

    //create a processBuilder for starting an operating system process
    ProcessBuilder pb = new ProcessBuilder("wscript", tempScript.toString());

    //start the process on the operating system
    Process process = pb.start();

    //tell the process how long to wait for timeout
    Boolean success = process.waitFor(timeout, minutes);
    if(!success) {
        System.out.println("Error: Could not print PDF within " + timeout + minutes);
    } else {
        System.out.println("Process to run visual basic script for pdf conversion succeeded.");
    }
    
} catch (Exception e) {
    e.printStackTrace();
    Alert saveAsPdfAlert = new Alert(AlertType.ERROR);
    saveAsPdfAlert.setTitle("ERROR: Error converting to pdf.");
    saveAsPdfAlert.setHeaderText("Exception message is:");
    saveAsPdfAlert.setContentText(e.getMessage());
    saveAsPdfAlert.showAndWait();  
}

VBS:

Option Explicit
Dim objExcel, strExcelPath, objSheet

strExcelPath = "XL_FILE"


Set objExcel = CreateObject("Excel.Application")
objExcel.WorkBooks.Open strExcelPath
Set objSheet = objExcel.ActiveWorkbook.Worksheets(1)

objSheet.ExportAsFixedFormat 0, "PDF_FILE",0, 1, 0, , , 0

objExcel.ActiveWorkbook.Close
objExcel.Application.Quit

這是完整的工作示例

依賴項:

compile 'com.itextpdf:itextpdf:5.5.13.2'
compile 'org.apache.poi:poi-ooxml:5.0.0'

爪哇代碼:

import java.io.*;
import org.apache.poi.ss.usermodel.*;

import java.util.Iterator;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;

public class Excel2PDF {
    public static void main(String[] args) throws Exception {

        Workbook my_xls_workbook = WorkbookFactory.create(new File("/Users/harshad/Desktop/excel.xlsx"));

        Sheet my_worksheet = my_xls_workbook.getSheetAt(0);

        short availableColumns = my_worksheet.getRow(0).getLastCellNum();
        System.out.println("Available columns : " + availableColumns);

        Iterator<Row> rowIterator = my_worksheet.iterator();

        Document iText_xls_2_pdf = new Document();
        PdfWriter.getInstance(iText_xls_2_pdf, new FileOutputStream("/Users/harshad/Desktop/excel.pdf"));
        iText_xls_2_pdf.open();

        PdfPTable my_table = new PdfPTable(availableColumns);

        PdfPCell table_cell = null;

        while (rowIterator.hasNext()) {
            Row row = rowIterator.next();
            Iterator<Cell> cellIterator = row.cellIterator();

            while (cellIterator.hasNext()) {
                Cell cell = cellIterator.next();

                switch (cell.getCellType()) {
                    default:
                        try {
                            table_cell = new PdfPCell(new Phrase(cell.getStringCellValue()));
                        } catch (IllegalStateException illegalStateException) {
                            //TODO: Need to handle exceptions for different type too
                            if (illegalStateException.getMessage().equals("Cannot get a STRING value from a NUMERIC cell")) {
                                table_cell = new PdfPCell(new Phrase(String.valueOf(cell.getNumericCellValue())));
                            }
                        }

                        my_table.addCell(table_cell);
                        break;
                }
            }
        }
        iText_xls_2_pdf.add(my_table);
        iText_xls_2_pdf.close();
        my_xls_workbook.close();
    }
}

另一種方法是使用 VB 腳本並從 Java 中調用它。

例子:

xl2pdf.vbs

Option Explicit
Dim objExcel, strExcelPath, objSheet

strExcelPath = "$XL_FILE"

Set objExcel = CreateObject("Excel.Application")
objExcel.WorkBooks.Open strExcelPath
Set objSheet = objExcel.ActiveWorkbook.Worksheets(1)

objSheet.ExportAsFixedFormat 0, "$PDF_FILE",0, 1, 0, , , 0

objExcel.ActiveWorkbook.Close
objExcel.Application.Quit

在 Java 中(實際上是 kotlin,但易於翻譯)

fun xl2pdf(xlFile: Path, pdfFile: Path, timeout: Long = 1, timeUnit: TimeUnit = TimeUnit.MINUTES) {
  val tempScript = Files.createTempFile("script", ".vbs")
  val script = Files.readAllLines(Paths.get("xl2pdf.vbs"))
          .map { it.replace("\$XL_FILE", "$xlFile") }
          .map { it.replace("\$PDF_FILE", "$pdfFile") }
  Files.write(tempScript, script)
  try {
    val pb = ProcessBuilder("wscript", tempScript.toString())
    val process = pb.start()
    val success = process.waitFor(timeout, timeUnit)
    if (!success) LOG.error("Could not print PDF within $timeout $timeUnit")
  } catch (e: IOException) {
    LOG.error("Error while printing Excel file to PDF", e)
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM