Hirdetés

Keresés

Új hozzászólás Aktív témák

  • E.Kaufmann
    veterán

    Ha valakinek kellene DOCX "sablon" (változókkal ellátott DOCX doksi) kitöltése Apache POI-val (és StringUtils-szal), akkor itt az én módszerem.
    Két-három StackOverFlow-os példát kicsit össze kellett gyúrni, hogy megtalálja a változókat és sortörést és formázást is jól kezeljen:
    A lényeg, hogy a változónevek a docx-ben ${változónév} formában szerepeljenek, valamint a változók és a helyettesítő szövegek egy HashMap<String,String> objektumban vannak, ahol a key a változónév csupaszon, a value meg a helyettesítő érték.
    Docx4j így kezelte, és nem akartam mindent újraírni.
    Mindenesetre mind az IDE mind a java fellélegzett, hogy kiszedtem a Docx4j-t meg a függőségeit :D
    private static void removeAllRuns(XWPFParagraph paragraph) {
    int size = paragraph.getRuns().size();
    for (int i = 0; i < size; i++) {
    paragraph.removeRun(0);
    }
    }

    private static void insertReplacementRuns(
    XWPFParagraph paragraph, String replacedText,
    String fontFamily, int fontSize)
    {
    String[] replacementTextSplitOnCarriageReturn = StringUtils.split(replacedText, "\n");
    XWPFRun newRun = paragraph.insertNewRun(0);
    newRun.setFontFamily(fontFamily);
    newRun.setFontSize(fontSize);
    String part = replacementTextSplitOnCarriageReturn[0];
    newRun.setText(part,0);
    for (int j = 1; j < replacementTextSplitOnCarriageReturn.length; j++) {
    part = replacementTextSplitOnCarriageReturn[j];
    newRun.addBreak();
    newRun.setText(part);
    }
    }

    public static void poiReplace(java.util.HashMap<String,String> hs, String in, String out) throws Exception
    {
    XWPFDocument doc = new XWPFDocument(new java.io.FileInputStream(in));
    for (XWPFParagraph p : doc.getParagraphs()) {
    String text = p.getText();
    boolean change=false;
    for ( String key : hs.keySet() ) {
    if (text != null && text.contains("${"+key+"}")) {
    text = text.replace("${"+key+"}", hs.get(key));
    change=true;
    System.out.println("\nx\n"+p.getText()+"\n"+key+"\n"+hs.get(key));
    }
    }

    if(change){
    List<XWPFRun> runs = p.getRuns();

    if (runs != null) {
    String ff=runs.get(0).getFontFamily();
    int fs=runs.get(0).getFontSize();
    removeAllRuns(p);
    insertReplacementRuns(p,text,ff,fs);
    }
    }
    }

    for (XWPFTable tbl : doc.getTables()) {
    for (XWPFTableRow row : tbl.getRows()) {
    for (XWPFTableCell cell : row.getTableCells()) {
    for (XWPFParagraph p : cell.getParagraphs()) {
    String text = p.getText();

    boolean change=false;
    for ( String key : hs.keySet() ) {
    if (text != null && text.contains("${"+key+"}")) {
    text = text.replace("${"+key+"}", hs.get(key));
    change=true;
    }
    }

    if(change){
    List<XWPFRun> runs = p.getRuns();

    if (runs != null) {
    String ff=runs.get(0).getFontFamily();
    int fs=runs.get(0).getFontSize();
    removeAllRuns(p);
    insertReplacementRuns(p,text,ff,fs);
    }
    }
    }
    }
    }
    }
    doc.write(new java.io.FileOutputStream(out));
    doc.close();


    }

    A poiReplace függvényt kell hívni, a másik kettőt meg a poiReplace hívogatja.

    Tegnap picit még püföltem a kódon:
    - kettévettem a poireplace függvényt,
    - megcsináltam, hogy elvileg működjön fejléccel és lábléccel is, de ez nem lett alaposabban tesztelve
    - néha írt hibaüzeneteket a Word, hogy a fájl meg van már nyitva, így bezártam az input és output állományt is a függvény végén
    - kicsit sztrímesítettem, ha valakinek gondja lenne vele, távolítsa el a kódból elsőnek a .parallel() részeket:
    private static void paragReplace(XWPFParagraph p,java.util.HashMap<String,String> hs){
    String text = p.getText();

    boolean change=false;
    for ( String key : hs.keySet() ) {
    if (text != null && text.contains("${"+key+"}")) {
    text = text.replace("${"+key+"}", hs.get(key));
    change=true;
    }
    }

    if(change){
    List<XWPFRun> runs = p.getRuns();

    if (runs != null) {
    String ff=runs.get(0).getFontFamily();
    int fs=runs.get(0).getFontSize();
    removeAllRuns(p);
    insertReplacementRuns(p,text,ff,fs);
    }
    }
    }

    public static void poiReplace(java.util.HashMap<String,String> hs, String in, String out) throws Exception
    {
    //Bekezdések
    java.io.FileInputStream ins=new java.io.FileInputStream(in);
    XWPFDocument doc = new XWPFDocument(ins);
    doc.getParagraphs().stream().parallel()
    .forEach((p) -> {
    paragReplace(p,hs);
    }
    );

    //Táblázatok
    doc.getTables().stream().parallel()
    .forEach((tbl) -> {tbl.getRows().stream()
    .forEach((row) -> {row.getTableCells().stream()
    .forEach((cell) -> {cell.getParagraphs().stream()
    .forEach((p) -> {
    paragReplace(p,hs);
    });
    });
    });
    }
    );

    //Fejléc bekezdések és táblázatok
    doc.getHeaderList().stream().forEach( (hdr) ->
    {

    hdr.getParagraphs().stream().parallel()
    .forEach((p) -> {
    paragReplace(p,hs);
    });

    hdr.getTables().stream().parallel()
    .forEach((tbl) -> {tbl.getRows().stream()
    .forEach((row) -> {row.getTableCells().stream()
    .forEach((cell) -> {cell.getParagraphs().stream()
    .forEach((p) -> {
    paragReplace(p,hs);
    });
    });
    });
    });

    }
    );

    //Lábléc bekezdések és táblázatok
    doc.getFooterList().stream().forEach( (ftr) ->
    {

    ftr.getParagraphs().stream().parallel()
    .forEach((p) -> {
    paragReplace(p,hs);
    });

    ftr.getTables().stream().parallel()
    .forEach((tbl) -> {tbl.getRows().stream()
    .forEach((row) -> {row.getTableCells().stream()
    .forEach((cell) -> {cell.getParagraphs().stream()
    .forEach((p) -> {
    paragReplace(p,hs);
    });
    });
    });
    });

    }
    );

    doc.write(new java.io.FileOutputStream(out));
    doc.close();
    ins.close();
    }

Új hozzászólás Aktív témák