【问题标题】:Creating PDF file in java using PDDocument results in corrupted PDF files使用 PDDocument 在 Java 中创建 PDF 文件会导致 PDF 文件损坏
【发布时间】:2019-09-24 05:28:52
【问题描述】:

我正在尝试使用 PDDocument 在 Java 中创建临时的 PDF 文件。我正在使用以下方法来创建一个临时的PDF 文件。

/* Create a temporary PDF file.*/
private File createPdf(String fileName) throws IOException {
    final PDDocument document = new PDDocument();
    final File file = File.createTempFile(fileName, ".pdf");
    //write it
    BufferedWriter bw = new BufferedWriter(new FileWriter(file));
    bw.write("This is the temporary pdf file content");
    bw.close();
    document.save(file);        
    document.close();
    return file;
}

这是测试。

@Test
public void testCreateAndMergePdfs() throws IOException {
    Collection<File> pdfs = new ArrayList<>(Arrays.asList(createPdf("File1"), createPdf("File2")));
    assertFalse(CollectionUtils.isEmpty(pdfs));
    PdfPrintPojo pdfPrintPojo = new PdfPrintPojo(pdfs);
    File mergedFile = service.createAndMergePDFs(pdfPrintPojo, "Merged");
    assertNotNull(mergedFile);
    List<File> list = new ArrayList<>(pdfs);
    File file1 = list.get(0);
    File file2 = list.get(1);
    assertTrue(FileUtils.contentEquals(file1, file2));
}

我在这里要做的是创建和合并两个PDF 文件。当我运行测试时,它会在temp 文件夹中创建两个PDF 文件,例如\AppData\Local\Temp\File16375814641476797612.pdf\AppData\Local\Temp\File24102718409195239661.pdf 以及\AppData\Local\Temp\Merged_merged_3755858389884894769.pdf 的合并文件。但测试失败 assertTrue(FileUtils.contentEquals(file1, file2)); 当我尝试打开temp 文件夹中的PDF 文件时,它说PDF 已损坏。另外,我不知道为什么文件没有保存为File1File2。谁能帮我这个?

【问题讨论】:

  • 你的 createAndMergePDFs 方法在哪里?
  • @Mak 它在服务类中,我认为这在这里不太重要。

标签: java file pdf pdfbox


【解决方案1】:

使用Apache PDFBox 教程,我设法创建了一个工作 PDF 文件。方法更改如下。

/* Create a temporary PDF file.*/
private File createPdf(String fileName) throws IOException {
    // Create a document and add a page to it
    final PDDocument document = new PDDocument();
    PDPage page = new PDPage();
    document.addPage(page);

    // Create a new font object selecting one of the PDF base fonts
    PDFont font = PDType1Font.HELVETICA_BOLD;

    // Start a new content stream which will "hold" the to be created content
    PDPageContentStream contentStream = new PDPageContentStream(document, page);

    // Define a text content stream using the selected font, moving the cursor and drawing the text "Hello World"
    contentStream.beginText();
    contentStream.setFont(font, 12);
    contentStream.newLineAtOffset(100, 700);
    contentStream.showText("Hello World");
    contentStream.endText();

    // Make sure that the content stream is closed:
    contentStream.close();

    // Save the results and ensure that the document is properly closed:
    File file = File.createTempFile(fileName, ".pdf");
    document.save(file);
    document.close();
    return file;
}

至于测试,我采用了使用PDDocument 加载文件的方法,然后使用PDFTextStripper 将数据提取为字符串并在这些字符串上使用断言。

 @Test
public void testCreateAndMergePdfs() throws IOException {
    Collection<File> pdfs = new ArrayList<>(Arrays.asList(createPdf("File1"), createPdf("File2")));
    assertFalse(CollectionUtils.isEmpty(pdfs));
    PdfPrintPojo pdfPrintPojo = new PdfPrintPojo(pdfs);
    File mergedFile = service.createAndMergePDFs(pdfPrintPojo, "Merged");
    assertNotNull(mergedFile);
    List<File> list = new ArrayList<>(pdfs);

    /* Load the PDF files and extract data as String. */
    PDDocument document1 = PDDocument.load(list.get(0));
    PDDocument document2 = PDDocument.load(list.get(1));
    PDDocument merged = PDDocument.load(mergedFile);

    PDFTextStripper stripper = new PDFTextStripper();
    String file1Data = stripper.getText(document1);
    String file2Data = stripper.getText(document2);
    String mergedData = stripper.getText(merged);

    /* Assert that data from file 1 and 2 are equal with each other and merged file. */
    assertEquals(file1Data, file2Data);
    assertEquals(file1Data + file2Data, mergedData);
}

【讨论】:

    【解决方案2】:

    你比较文件内容的方式有点不同,你可以试试下面,

    @Test
    public void testCreateAndMergePdfs() {
        Assert.assertEquals(FileUtils.readLines(file1), FileUtils.readLines(file2));
    } 
    

    或者你可以试试

        byte[] file1Bytes = Files.readAllBytes(Paths.get("Path to File 1"));
        byte[] file2Bytes = Files.readAllBytes(Paths.get("Path to File 2"));
    
        String file1 = new String(file1Bytes, StandardCharsets.UTF_8);
        String file2 = new String(file2Bytes, StandardCharsets.UTF_8);
    
        assertEquals("The content in the strings should match", file1, file2);
    

    或者

        File file1 = new File(file1);
        File file2 = new File(file2);
        assertThat(file1).hasSameContentAs(file2);
    

    【讨论】:

    • 它给出了断言错误。我设法将 PDF 合并并以某种方式工作,现在我需要确保合并文件的内容等于 file1 和 file2 的内容。我该怎么做?
    • 你能从上面检查吗,只需将文件中的内容作为字符串,并将合并的文件内容作为字符串检查。或者用户 hasSameContentAs 方法
    • 设法修复它使用 PDFTextStripper 从 PDF 中提取数据,作为字符串和这些字符串上使用的断言。
    • 好。如果以上答案对您有用,请点赞并采纳。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-01
    • 1970-01-01
    相关资源
    最近更新 更多