2016-11-11 4 views
1

Я пишу код для чтения .doc-файла в качестве шаблона и записи данных в новый .doc-файл после различных итераций. У моего кода, похоже, есть простая проблема, которую я не могу понять.Java Apache POI: чтение/запись из .doc-файла

Ниже приведен код, который я написал, [я получил основной скелет где-то на StackOverflow только.]

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

}

код работает без каких-либо проблем. Вот как выглядит input.doc, input.doc

После успешного запуска также выводится output.doc. Но проблема в том, что он содержит данные только для первого цикла.

Идеально, он должен содержать данные для всех трех итераций, но он содержит данные только для первого, а затем ничего. Он также не показывает никаких ошибок/исключений во время выполнения. Я также удостоверился, что выходной поток будет иметь параметр append как true.

Это как output.doc выглядит, output.doc

Не уверен, что я делаю неправильно.

Когда я запускаю программу, я могу видеть в приведенном ниже примере

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...

Как я инициируя входной файл как новый в каждой итерации. Таким образом, я нахожу все элементы $ во время итерации. Просто они не добавляются в окончательный файл.

Может быть, пожалуйста, помогите пожалуйста? Большое спасибо.

ответ

0

По-видимому, и удивительно, что Apache POI не имеет какой-либо метод, чтобы писать добавить к существующему документу слова. Таким образом, вышеприведенный подход не работает.

Я также пробовал Apache FileUtils, но он не сохраняет форматирование слова документа. Я также пробовал docx4j, но только работает над файлами docx и оплачивается его класс утилизации.

Существует еще одна структура, Aspose Words, которая обеспечивает гораздо лучший контроль и гибкость. Он позволяет добавлять содержимое к существующему документу с ограничением в 1150 символов. Но это слишком много для моего требования, чтобы беспокоиться, поскольку мое письмо было не более чем установленным лимитом.

Поэтому я использовал это для достижения того, что хотел. Наконец-то это успех.

Спасибо за помощь @D. Krauchanka

1

Вы открываете файл шаблона, меняя контент и сохраняя его на «F: \ docx \ output.doc». Вы делаете это 3 раза и каждый раз, когда вы перезаписываете выходной файл.

Будет намного лучше подготовить строку в цикле, а затем только один раз заменить в документе. Ваш метод main будет выглядеть следующим образом:

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

Я добавил вывод на консоль выше, который я вижу при запуске программы.Он также указал, что элементы $ найдены и заменены на каждую итерацию. – WebNoob

+0

Да, я был немного не прав), вы открываете свой файл шаблона, меняя контент и сохраняя его на «F: \\ docx \\ output.doc». Вы делаете это 3 раза и каждый раз, когда вы перезаписываете выходной файл. Итак, попробуйте решение, которое я вам предоставил. –

+0

На самом деле содержимое, о котором я показываю, является фиктивным содержимым, для простоты читаемым для всех. Фактическим содержимым будут имена файлов с контуром, которые также будут содержать специальные символы в имени файла или пути к файлу. Поэтому, если я попытаюсь добавить это в строку, он сломается из-за него. То, что я имею прямо сейчас, прекрасно работает. Единственная проблема - я не знаю ни одного метода в POI, который бы помог мне добавить содержимое всех итераций в один файл. Знаете ли вы о какой-либо другой технике, которая может работать. – WebNoob