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.*; import org.springframework.boot.context.event.ApplicationStartedEvent; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; import org.springframework.util.ResourceUtils; import vin.vio.usepoitl.model.TableData; import java.io.File; 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"); Configure config = Configure.builder() .addPlugin('&', new LoopRowTableRenderPolicy()).build(); XWPFTemplate allTemplate = XWPFTemplate.compile(wordFile.getAbsolutePath(), config); List list = allTemplate.getElementTemplates(); boolean onSameLine = false; Pattern pattern = Pattern.compile("\\[(.*?)\\]"); log.info("=====all tag====="); for (MetaTemplate metaTemplate : list) { if (metaTemplate instanceof ElementTemplate ele) { log.info(ele.getTagName()); String source = ele.getSource(); if (!source.contains("&")) { continue; } } if (metaTemplate instanceof RunTemplate runTemplate) { XWPFRun run = runTemplate.getRun(); XWPFTableCell tagCell = (XWPFTableCell) ((XWPFParagraph) run.getParent()).getBody(); XWPFTable table = tagCell.getTableRow().getTable(); int templateRowIndex = getTemplateRowIndex(tagCell, onSameLine); XWPFTableRow row = table.getRow(templateRowIndex); for (XWPFTableCell cell : row.getTableCells()) { String text = cell.getText(); Matcher matcher = pattern.matcher(text); while (matcher.find()) { String colTag = matcher.group(1); log.info("colTag {}", colTag); } } } } log.info("=====all tag=====END"); 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")); } private int getTemplateRowIndex(XWPFTableCell tagCell, boolean onSameLine) { XWPFTableRow tagRow = tagCell.getTableRow(); return onSameLine ? getRowIndex(tagRow) : (getRowIndex(tagRow) + 1); } private int getRowIndex(XWPFTableRow row) { List rows = row.getTable().getRows(); return rows.indexOf(row); } }