【问题标题】:Java Apache POI Excel save as PDFJava Apache POI Excel 另存为 PDF
【发布时间】:2014-11-21 06:48:01
【问题描述】:

如何将excel 文件转换/保存为pdf?我正在使用java play framework 生成一些excel 文件,现在需求更改为pdf。我不想重新编码所有内容。

有没有办法转换成pdf

我生成的excel 文件来自模板;我阅读了 excel 模板文件,编写了更改,然后另存为新的 excel 文件。这样,模板就不会改变。它包含边框、图像和其他格式。

【问题讨论】:

    标签: java excel pdf playframework-2.0 apache-poi


    【解决方案1】:

    您需要以下 Java 库和相关的 JAR 文件才能使程序运行。 POI 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
                }
        }
    

    希望对你有帮助

    【讨论】:

    • 面临这个问题:提供的数据似乎在 Office 2007+ XML 中。您正在调用处理 OLE2 Office 文档的 POI 部分。您需要调用 POI 的不同部分来处理这些数据(例如 XSSF 而不是 HSSF)
    【解决方案2】:

    另一种方法是使用 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)
      }
    }
    

    【讨论】:

      【解决方案3】:

      添加到 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
      

      【讨论】:

        【解决方案4】:

        这是完整的工作示例

        依赖关系:

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

        Java 代码:

        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();
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-04-12
          • 2017-04-18
          • 1970-01-01
          相关资源
          最近更新 更多