Copy Pdf s with itext fields do not appear

Asked

Viewed 65 times

1

I have a routine that generates several pdf s with data from the database, using a template created in Openoffice, this contains several fields that are filled with data from the database, in the end are generated many files, so I merge these having as a final a single pdf, the problem is that the values of the fields are not visible however, when clicking on any of these fields we perceive the information.

I’m using itext version 5.5.9 below follows the method that creates the final file, also report that the problem is only in the final pdf, so how or what should I do to get a PDF that is the copy of the other files because I’ve already looked at the library documentation, I have already sought information of problems identical to mine and I saw that there are more I did not understand how to solve.

private static void mergeFiles(List<PdfReader> readers, String dest) throws DocumentException, IOException {

    Document document = new Document();
    PdfCopy copy = new PdfSmartCopy(document, new FileOutputStream(dest));
    //copy.setMergeFields();
    document.open();

    for (PdfReader r : readers) {
        copy.addDocument(r);
        r.close();
    }

    document.close();               
}

o que faz o rename dos campos

private static byte[] renameFields(String src, int i) throws IOException, DocumentException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    PdfReader reader = new PdfReader(src);
    PdfStamper stamper = new PdfStamper(reader, baos);
    AcroFields form = stamper.getAcroFields();
    Set<String> keys = new HashSet<String>(form.getFields().keySet());
    for (String key : keys) {
        form.renameField(key, String.format("%s_%d", key, i));
    }

    stamper.close();
    reader.close();
    return baos.toByteArray();
}

e o método que percorre a pasta que contém os arquivos que serão unidos/copiados
public static void unirPDF(String turma, String path, String destino) {

    File pasta = new File(path);    
    String arquivoDestino = destino + System.getProperty("file.separator") + turma + "_" ;

    ArrayList<File> arquivos;
    // Pegar apenas pdf
    arquivos = new ArrayList<>(Arrays.asList(pasta.listFiles( new FileFilter(){
       public boolean accept(File pathname){
           return pathname.getName().toLowerCase().endsWith(".pdf");
       }                
    })));

    try {

        int i = 0;
        int j = 0;

        //List<InputStream> pdfs = new ArrayList<InputStream>();
        List<PdfReader> readers = new ArrayList<PdfReader>();
        String cover =  path + System.getProperty("file.separator") + "Cover.pdf";  
        PdfReader reader = new PdfReader(renameFields(cover, ++i));
        readers.add(reader);
        //pdfs.add(new FileInputStream(arquivoCover));

        for (File arquivo : arquivos) {

            if (!arquivo.toString().contains("Cover")) {

               //pdfs.add(new FileInputStream(arquivo)  );                        
               reader = new PdfReader(renameFields(arquivo.getAbsolutePath(), ++i));                   
               readers.add(reader);                                    

               if (i > 200) {
                   j++;
                   i = 0;
                   mergeFiles(readers, arquivoDestino + String.valueOf(j) + ".pdf" );
                   //pdfs.clear();

                   for (PdfReader r : readers) {
                        r.close();
                    }
                   readers.clear();
               }
            }
        }   

        if (readers.size()>0) {
           j++;
           mergeFiles(readers, arquivoDestino + String.valueOf(j) + ".pdf" );
           //pdfs.clear();
           for (PdfReader r : readers) {
                r.close();
            }
           readers.clear();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

}

Providing a code for the behavior to be reproduced

Flow Service Class (Productoservice) contains a process method that gets the list of products and calls generating Dfdfs by passing this list

gerarPdfs will use the template file ( note not seen how to attach this file so without it will be difficult to try to reproduce), and generate the PDF s with the content/data of each product, a file for each product, the template is simple only has a field that will be the product name.

generated pdf s comes the Uniaopdf.unirPDF("G: Dev", "G: Pdf") method that will merge the files into one

class ProdutoService {
    public List<Produto> findAll() {

       Produto p1 = new Produto(1L, "Produto1");
       Produto p2 = new Produto(2L, "Produto2");
       Produto p3 = new Produto(5L, "Produto3");

       Produto[] produtos = {p1, p2, p3};

       return Arrays.asList(produtos);
    }

    void processar() throws IOException, DocumentException {

         List<Produto> produtos = findAll();

         gerarPdfs(produtos);

         // juntar pdf´s criados em um só
         UniaoPDF.unirPDF("G:\\Dev", "G:\\Pdf");        
     }

    void gerarPdfs(List<Produto> produtos) throws IOException, DocumentException {

         String template = "G:\\Dev\\ProdutoTemplate" + ".pdf";
         String arquivoSaida = "G:\\Dev\\Produto" ;  

         FileOutputStream saida = null;
         PdfReader leitor = null ;
         PdfStamper stamper = null ;

         // Gerar um pdf para cada produto
         for (Produto p: produtos) {

            saida = new FileOutputStream(arquivoSaida + String.valueOf(p.getId()) + ".pdf");
            leitor = new PdfReader(template);
            stamper = new PdfStamper(leitor, saida);
            AcroFields form = stamper.getAcroFields();
            form.setField("txtNome", p.getNome().toString());
            stamper.close();
            saida.flush();
            saida.close();
            leitor.close();     
         }
     }

  }



class UniaoPDF {
      public static void unirPDF(String path, String destino) {

           File pasta = new File(path); 
           String arquivoDestino = destino + System.getProperty("file.separator") + "produtos.pdf" ;

           ArrayList<File> arquivos;
              // Pegar apenas arquivos pdf da pasta
              arquivos = new ArrayList<>(Arrays.asList(pasta.listFiles( new FileFilter(){
           public boolean accept(File pathname){
               return pathname.getName().toLowerCase().endsWith(".pdf");
           }                
        })));

              try {

                  int i = 0;
                  List<PdfReader> readers = new ArrayList<PdfReader>();
                  PdfReader reader;

                  for (File arquivo : arquivos) {

                     reader = new PdfReader(renameFields(arquivo.getAbsolutePath(), ++i));                   
                     readers.add(reader);                                                       
                  } 

                  if (readers.size()>0) {
                     mergeFiles(readers, arquivoDestino);
                     for (PdfReader r : readers) {
                          r.close();
                      }
                     readers.clear();
                  }
              } catch (Exception e) {
                  e.printStackTrace();
              } 
      } 

      private static byte[] renameFields(String src, int i) throws IOException, DocumentException {
          ByteArrayOutputStream baos = new ByteArrayOutputStream();
          PdfReader reader = new PdfReader(src);
          PdfStamper stamper = new PdfStamper(reader, baos);
          AcroFields form = stamper.getAcroFields();
          Set<String> keys = new HashSet<String>(form.getFields().keySet());
          for (String key : keys) {
              form.renameField(key, String.format("%s_%d", key, i));
          }

          stamper.close();
          reader.close();
          return baos.toByteArray();
      }

      static void mergeFiles(List<PdfReader> readers, String dest) throws DocumentException, IOException {

          Document document = new Document();
          PdfCopy copy = new PdfSmartCopy(document, new FileOutputStream(dest));
          //copy.setMergeFields();
          document.open();

          for (PdfReader r : readers) {
              copy.addDocument(r);
              r.close();
          }

          document.close();             
      }

 }
  • 2

    Please provide a [mcve] of your code so it is possible to test and reproduce the problem.

  • Hello Articuno, I updated the code so that the behavior can be tested

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.