package vin.vio.usepoitl.exec; import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.config.Configure; import com.deepoove.poi.data.*; import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy; import com.deepoove.poi.template.ElementTemplate; import com.deepoove.poi.template.MetaTemplate; import com.deepoove.poi.template.run.RunTemplate; import lombok.extern.slf4j.Slf4j; import org.apache.poi.xwpf.usermodel.XWPFRun; import org.apache.poi.xwpf.usermodel.XWPFTableCell; import org.apache.poi.xwpf.usermodel.XWPFTableRow; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.event.ApplicationStartedEvent; import org.springframework.context.ApplicationListener; import org.springframework.core.io.ResourceLoader; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import org.springframework.util.ResourceUtils; import vin.vio.usepoitl.model.TableData; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.math.BigDecimal; import java.math.RoundingMode; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * @Description: TODO * @Date: 2025/2/28 16:18 * @Created: by ZZSLL */ @Component @Slf4j public class ApplicationStartExec implements ApplicationListener { @Override public void onApplicationEvent(ApplicationStartedEvent e) { log.info("==================="); log.info("Application started"); log.info("==================="); try { doReplace(); } catch (IOException ex) { ex.printStackTrace(); throw new RuntimeException(ex); } } public void doReplace() throws IOException { File wordFile = ResourceUtils.getFile("classpath:file/EHSP-MFX250222-A.docx"); File image = ResourceUtils.getFile("classpath:file/bafybeigrxcfikrzuksedvman4cebmao2jhre436vjxfukascqwxv2px5fa.png"); Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); XWPFTemplate allTemplate = XWPFTemplate.compile(wordFile.getAbsolutePath()); List list = allTemplate.getElementTemplates(); log.info("=====all tag====="); for (MetaTemplate metaTemplate : list) { if (metaTemplate instanceof ElementTemplate ele) { log.info(ele.getTagName()); XWPFRun run = ((RunTemplate) ele).getRun(); if (run.getParent() instanceof XWPFTableCell) { XWPFTableCell cell = (XWPFTableCell) run.getParent(); XWPFTableRow row = cell.getTableRow(); List cells = row.getTableCells(); for (XWPFTableCell tableCell : cells) { String cellText = tableCell.getText(); Pattern pattern = Pattern.compile("\\[(.*?)\\]"); Matcher matcher = pattern.matcher(cellText); while (matcher.find()) { String colTag = matcher.group(1); log.info("colTag {} {}", ele.getTagName(),colTag); } } } } } log.info("=====all tag=====END"); LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy(); Configure config = Configure.builder() .bind("table", policy).build(); List tableDate = new ArrayList<>(); BigDecimal total_qty = BigDecimal.ZERO; BigDecimal total_amt = BigDecimal.ZERO; for (int i = 0; i < 12; i++) { BigDecimal qty = new BigDecimal(i); total_qty = total_qty.add(qty); BigDecimal price = new BigDecimal("10." + i); BigDecimal amt = qty.multiply(price); total_amt = total_amt.add(amt); tableDate.add(TableData.builder() .index(i) .m_code("AAA__" + i) .m_name("BBB___" + i) .m_qty(qty.setScale(2, RoundingMode.HALF_UP).toPlainString()) .m_unit_price(price.setScale(2, RoundingMode.HALF_UP).toPlainString()) .m_amount(amt.setScale(2, RoundingMode.HALF_UP).toPlainString()) .build()); } BigDecimal finalTotal_qty = total_qty; BigDecimal finalTotal_amt = total_amt; XWPFTemplate template = XWPFTemplate.compile(wordFile.getAbsolutePath(), config).render( new HashMap() {{ put("table", tableDate); put("billno", Texts.of("YXZG-250228-ZZS").color("dc2626").create()); put("biz_date", sdf.format(date)); put("address", "中国西安雁塔"); put("image", Pictures.ofLocal(image.getAbsolutePath()).size(50, 50).create()); put("total_qty", finalTotal_qty.setScale(2, RoundingMode.HALF_UP).toPlainString()); put("total_amount", finalTotal_amt.setScale(2, RoundingMode.HALF_UP).toPlainString()); }}); template.writeAndClose(new FileOutputStream("output.docx")); } }