How to copy some content in one .docx to another .docx using POI without losing format?

Suppose I have two .docx files input.docx

and output.docx

I need to select some of the content in input.docx

and copy them to output.docx

. newdoc

displays its contents in the console seems to be correct, but I got nothing in output.docx

other than blank lines. Can anyone give some advice?

InputStream is = new FileInputStream("D:\\input.docx"); 
XWPFDocument doc = new XWPFDocument(is);

List<XWPFParagraph> paras = doc.getParagraphs();  
List<XWPFRun> runs;
XWPFDocument newdoc = new XWPFDocument();                                     
for (XWPFParagraph para : paras) {  
            runs = para.getRuns();      
            if(!para.isEmpty())
            {
                XWPFParagraph newpara = newdoc.createParagraph(); 
                XWPFRun newrun = newpara.createRun();
                for (int i=0; i<runs.size(); i++) {                       
                    newrun=runs.get(i);
                    newpara.addRun(newrun);
                }
            }
        }


        List<XWPFParagraph> newparas = newdoc.getParagraphs(); 
        for (XWPFParagraph para1 : newparas) {  
            System.out.println(para1.getParagraphText());
        }// in the console, I have the correct information

        FileOutputStream fos = new FileOutputStream(new File("D:\\output.docx"));
        newdoc.write(fos);
        fos.flush();
        fos.close();

      

+3


source to share


1 answer


I modified your code a bit, it copies the text without changing the text format.

public static void main(String[] args) {
    try {
        InputStream is = new FileInputStream("Japan.docx"); 
        XWPFDocument doc = new XWPFDocument(is);

        List<XWPFParagraph> paras = doc.getParagraphs();  

        XWPFDocument newdoc = new XWPFDocument();                                     
        for (XWPFParagraph para : paras) {  

            if (!para.getParagraphText().isEmpty()) {       
                XWPFParagraph newpara = newdoc.createParagraph();
                copyAllRunsToAnotherParagraph(para, newpara);
            }

        }

        FileOutputStream fos = new FileOutputStream(new File("newJapan.docx"));
        newdoc.write(fos);
        fos.flush();
        fos.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

// Copy all runs from one paragraph to another, keeping the style unchanged
private static void copyAllRunsToAnotherParagraph(XWPFParagraph oldPar, XWPFParagraph newPar) {
    final int DEFAULT_FONT_SIZE = 10;

    for (XWPFRun run : oldPar.getRuns()) {  
        String textInRun = run.getText(0);
        if (textInRun == null || textInRun.isEmpty()) {
            continue;
        }

        int fontSize = run.getFontSize();
        System.out.println("run text = '" + textInRun + "' , fontSize = " + fontSize); 

        XWPFRun newRun = newPar.createRun();

        // Copy text
        newRun.setText(textInRun);

        // Apply the same style
        newRun.setFontSize( ( fontSize == -1) ? DEFAULT_FONT_SIZE : run.getFontSize() );    
        newRun.setFontFamily( run.getFontFamily() );
        newRun.setBold( run.isBold() );
        newRun.setItalic( run.isItalic() );
        newRun.setStrike( run.isStrike() );
        newRun.setColor( run.getColor() );
    }   
}

      

There is still a small problem with fontSize . Sometimes the POI can't figure out the run size (I write its value to the console to track it) and gives -1. It detects the font size fine when I set it myself (say I select a few paragraphs in Word and set its font manually, be it size or font family). But when it processes other text generated by the POI, it sometimes gives -1. So I set the default font size (10 in the above example) which is set when the POI gives -1.



There is another problem with the Calibri font family. But in my tests, POI sets it to Arial by default, so I don't have the same trick with default fontFamily as I did for fontSize.

Other font properties (bold, italic, etc.) work well.

Probably all these font problems are due to the fact that in my tests the text was copied from the .doc file. If you have .doc as input, open the .doc file in Word, then "Save As .." and select the .docx format. Then in your program use only XWPFDocument

instead HWPFDocument

and I suppose everything will be fine.

+3


source







All Articles