如何使用POI将一个.docx中的某些内容复制到另一个.docx中,而又不会丢失格式?

问题描述 投票:5回答:2

假设我有两个.docx文件,input.docxoutput.docx,我需要选择input.docx中的某些内容并将其复制到output.docxnewdoc在控制台中显示其内容似乎正确,但是output.docx除了空白行外什么都没得到。谁能提供建议?

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();
java apache-poi
2个回答
5
投票

我稍微修改了您的代码,它在不更改文本格式的情况下复制文本。

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

fontSize仍然存在一些问题。有时,POI无法确定运行的大小(我将其值写入控制台以跟踪它)并给出-1。当我自己设置字体时,它可以完美地定义字体的大小(例如,我在Word中选择一些段落并手动设置其字体,无论是大小还是字体系列)。但是当它处理另一个POI生成的文本时,有时会给出-1。因此,当POI给出-1时,我会引入一个默认字体大小(在上面的示例中为10)。

[Calibri字体家族似乎出现了另一个问题。但是在我的测试中,POI默认情况下将其设置为Arial,因此我对默认fontFamily没有相同的技巧,就像对fontSize一样。

其他字体属性(粗体,斜体等)效果很好。

[可能所有这些字体问题都是由于在我的测试中,文本是从.doc文件复制而来的。如果输入的是.doc,请在Word中打开.doc文件,然后单击“另存为..”,然后选择.docx格式。然后在您的程序中仅使用XWPFDocument而不是HWPFDocument,我想它会没事的。


0
投票

我正在看这段代码,它很好用,但是由于你们都熟悉java apache poi,所以我想问一下是否还有一种方法来保留编号列表?

谢谢,我将不胜感激。

© www.soinside.com 2019 - 2024. All rights reserved.