2016-11-11 3 views
1

J'écris un code pour lire un fichier .doc en tant que modèle et écrire des données dans le nouveau fichier .doc après diverses itérations. Mon code semble avoir un problème simple que je n'arrive pas à comprendre.Java Apache POI: lecture/écriture à partir du fichier .doc problème

est Ci-dessous le code que je l'ai écrit, [je suis arrivé squelette de base quelque part sur stackoverflow seulement.]

public class HWPFTest { 

    public static void main(String[] args) { 
     String inputFile = "F:\\docx\\input.doc"; 
     String outputFile = "F:\\docx\\output.doc"; 
     POIFSFileSystem fs = null; 

     try { 
       for (int i = 0; i < 3; i++) { 
        fs = new POIFSFileSystem(new FileInputStream(inputFile)); 
        HWPFDocument doc = new HWPFDocument(fs); 
        System.out.println("LOOOOOOOOOOOOP ----> " + i); 
        doc = replaceText(doc, "$count", String.valueOf(i)); 
        doc = replaceText(doc, "$filename", "FileName" + i); 
        doc = replaceText(doc, "$inputFile", "Input" + i); 
        doc = replaceText(doc, "$outputFile", "Output" + i); 
        doc = replaceText(doc, "$message", "Message" + i); 
        doc = replaceText(doc, "$snap", "Snapshot" + i); 
        saveWord(outputFile, doc); 
       } 
       System.out.println("DONE..."); 
     } 
     catch (FileNotFoundException e) { 
       e.printStackTrace(); 
     } catch (IOException e) { 
       e.printStackTrace(); 
     } 
    } 

    private static HWPFDocument replaceText(HWPFDocument doc, String findText, String replaceText) { 
     Range r1 = doc.getRange(); 
     for (int i = 0; i < r1.numSections(); ++i) { 
       Section s = r1.getSection(i); 
       for (int x = 0; x < s.numParagraphs(); x++) { 
        Paragraph p = s.getParagraph(x); 
        for (int z = 0; z < p.numCharacterRuns(); z++) { 
          CharacterRun run = p.getCharacterRun(z); 
          String text = run.text(); 
          if (text.contains(findText)) { 
           run.replaceText(findText, replaceText); 
           System.out.println("findText: " + findText + " replaceText: " + replaceText); 
          } 
        } 
       } 
     } 
     return doc; 
    } 


    private static void saveWord(String filePath, HWPFDocument doc) throws FileNotFoundException, IOException { 
     FileOutputStream out = null; 
     try { 
       // Add true to make the data append possible in output stream. 
       out = new FileOutputStream(filePath, true); 
       doc.write(out); 
       out.flush(); 
     } catch (Exception ex) { 
       ex.printStackTrace(); 
     } finally { 
       out.close(); 
     } 
    } 

}

Le code fonctionne sans aucun problème. Voici à quoi ressemble l'entrée.doc, input.doc

Après l'exécution réussie, output.doc est également généré. Mais le problème est qu'il contient des données pour seulement la première boucle. Idéalement, il doit contenir des données pour toutes les 3 itérations, mais il ne contient que des données pour le premier et ensuite il n'y a rien. Il ne montre aucune erreur/exception lors de l'exécution. J'ai également veillé à ce que outputtream ait l'option append aussi vraie.

Voici comment le output.doc ressemble, output.doc

Je ne sais pas ce que je fais mal.

Quand je lance le programme, je peux voir dans la sortie ci-dessous,

LOOOOOOOOOOOOP ----> 0 findText: $count replaceText: 0 findText: $filename replaceText: FileName0 findText: $inputFile replaceText: Input0 findText: $outputFile replaceText: Output0 findText: $message replaceText: Message0 findText: $snap replaceText: Snapshot0 LOOOOOOOOOOOOP ----> 1 findText: $count replaceText: 1 findText: $filename replaceText: FileName1 findText: $inputFile replaceText: Input1 findText: $outputFile replaceText: Output1 findText: $message replaceText: Message1 findText: $snap replaceText: Snapshot1 LOOOOOOOOOOOOP ----> 2 findText: $count replaceText: 2 findText: $filename replaceText: FileName2 findText: $inputFile replaceText: Input2 findText: $outputFile replaceText: Output2 findText: $message replaceText: Message2 findText: $snap replaceText: Snapshot2 DONE...

Comme j'entreprends le fichier d'entrée comme nouveau dans chaque itération. Donc, je trouve tous les éléments $ pendant l'itération. C'est juste qu'ils ne sont pas ajoutés dans le fichier final.

Quelqu'un peut-il aider s'il vous plaît ici? Merci beaucoup.

Répondre

0

Apparemment, et étonnamment, Apache POI n'a pas de méthode pour écrire avec append à un document Word existant. Donc, l'approche ci-dessus ne fonctionne pas.

J'ai également essayé Apache FileUtils, mais il ne conserve pas le formatage du document Word. J'ai également essayé docx4j, mais fonctionne uniquement sur les fichiers docx et sa classe d'utilitaire de fusion est payée.

Il existe un autre cadre, Aspose Words, qui offre un meilleur contrôle et une meilleure flexibilité. Il vous permet d'ajouter le contenu au document existant, avec une limite de 1150 caractères. Mais c'est beaucoup trop pour mon besoin de s'inquiéter car mon écriture n'était pas plus que la limite fixée. J'ai donc utilisé cela pour réaliser ce que je voulais faire. C'est un succès enfin.

Merci pour l'aide @D. Krauchanka

1

Vous ouvrez votre fichier de modèle, en changeant le contenu et en l'enregistrant dans "F: \ docx \ output.doc". Vous faites cela 3 fois et chaque fois que vous remplacez le fichier de sortie.

Il vaudra beaucoup mieux préparer la chaîne en boucle et seulement une fois remplacer dans le document. Votre méthode main ressemblera:

public static void main(String[] args) { 
     String inputFile = "F:\\docx\\input.doc"; 
     String outputFile = "F:\\docx\\output.doc"; 
     POIFSFileSystem fs = null; 

     String counts = ""; 

     try { 
      for (int i = 0; i < 3; i++) { 
       counts += String.valueOf(i) + "; "; 
      } 
      fs = new POIFSFileSystem(new FileInputStream(inputFile)); 
      HWPFDocument doc = new HWPFDocument(fs); 
      doc = replaceText(doc, "$count", counts); 
      saveWord(outputFile, doc); 
     } 
     catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
+0

J'ai ajouté la sortie de la console en question ci-dessus que je vois quand je cours le programme.Il a également indiqué que les éléments $ sont trouvés et remplacés à chaque itération. – WebNoob

+0

Oui, j'avais un peu tort) vous ouvrez votre fichier de modèle, en changeant le contenu et en sauvegardant dans "F: \\ docx \\ output.doc". Vous faites cela 3 fois et chaque fois que vous remplacez le fichier de sortie. Alors, essayez la solution que je vous ai fournie en réponse. –

+0

En fait, le contenu que je montre en question sont des contenus fictifs, pour que la simplicité soit lisible pour tout le monde. Le contenu réel sera des noms de fichiers avec le chemin, et qui contiendra également des caractères spéciaux dans le nom de fichier ou le chemin du fichier. Donc, si j'essaie d'ajouter cela dans la chaîne, il se cassera à cause de cela. Ce que j'ai en ce moment, fonctionne parfaitement. Le seul problème est que je ne connais aucune méthode dans POI qui m'aiderait à ajouter le contenu de toutes les itérations dans un seul fichier. Connaissez-vous d'autres techniques qui pourraient fonctionner? – WebNoob