This commit is contained in:
zzs 2025-02-28 18:22:50 +08:00
commit 2062d7b415
9 changed files with 315 additions and 0 deletions

33
.gitignore vendored Normal file
View File

@ -0,0 +1,33 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/

95
pom.xml Normal file
View File

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.9</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>vin.vio</groupId>
<artifactId>use-poi-tl</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>use-poi-tl</name>
<description>use-poi-tl</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.5</version>
</dependency>
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.12.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,15 @@
package vin.vio.usepoitl;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class UsePoiTlApplication {
public static void main(String[] args) {
SpringApplication.run(UsePoiTlApplication.class, args);
}
}

View File

@ -0,0 +1,132 @@
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<ApplicationStartedEvent> {
@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<MetaTemplate> 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<XWPFTableCell> 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<TableData> 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<String, Object>() {{
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"));
}
}

View File

@ -0,0 +1,26 @@
package vin.vio.usepoitl.model;
import lombok.Builder;
import lombok.Getter;
import java.math.BigDecimal;
/**
* @Description: TODO
* @Date: 2025/2/28 17:28
* @Created: by ZZSLL
*/
@Builder
@Getter
public class TableData {
private Integer index;
private String m_code;
private String m_name;
private String m_qty;
private String m_unit_price;
private String m_amount;
}

View File

@ -0,0 +1 @@
spring.application.name=use-poi-tl

View File

@ -0,0 +1,126 @@
销售合同
Sales Contract
Договор купли-продажи
合同号Contract Договор No.{{billno}}
日期 Date Дата: {{biz_date}}
地点The place Место: {{address}}
卖方The Seller Продавец:
Ensign Heavy Industries Co., Ltd.
Инсайн Хеви Индастриз Ко., Лтд
Add: No. 1567, Ensign Street, and Economic Development Zone,
Changle, Weifang, Shandong, China
Адрес: № 1567, Инcайн Стрит энд Экономик Девелопмент Зоун,
Чанле, Вейфань, Шаньдунь, Китай
Tel: +86-536-6295117 Fax: +86-536-6298797
Тел: +86 536 6296117, факс +86 536 6298797
Contact: Eda
Контактное лицо: Эда
Email: eda@ensignhi.com
Адрес эл.почты: eda@ensignhi.com
买方The Buyer Покупатель:
ТОО "Atameken-Energy"
Add/Адрес: КАЗАХСТАН, ТУРКЕСТАНСКАЯ обл, ТУРКЕСТАН г, ТУРКЕСТАН г, УЛИЦА А.ЮСУПОВ ул, дом 160
Contact / Контактное лицо: БОЛАТ НАГЫМЖАН
本合同由双方订立,根据本合同规定的条款,卖方同意出售,买方同意购买下列货物。
This contract is made by and between the Seller and Buyer, whereby the Seller agrees to sell and the Buyer agrees to buy the under mentioned commodity according to the terms and conditions stipulated below:
Настоящий договор заключен между Продавцом и Покупателем, согласно чему, Продавец продает, а Покупатель покупает нижеуказанный товар, в соответствии с условиями и сроками, определенными ниже:
商品名称及价格 Commodity, Quantity, Unit price and Total Value:
Товар, количество, цена за единицу, общая стоимость
Name, range, quantity, and price of Goods for every lot, as well as delivery period will be specified in
No.
п/п
PART NO.
Номер детали
PART NAME
Наименование детали
QTY
Кол-во
Unit Price
Цена за ед.
Total price
Цена итого
FCA Ensign factory in CNY{{table}}
[index]
[m_code]
[m_name]
[m_qty]
[m_unit_price]
[m_amount]
TOTAL QUANTITY: {{total_qty}}
212Pcs
TOTAL AMOUNT: {{total_amount}}
CNY10000
SAY TOTAL:CHINESE YUAN TENTHOUSAND ONLY.
包装Packing Упаковка: 装于箱内Packed in boxes Упаковано в коробки
装运期Time of Shipment Время отгрузки: 2025年3月Before in March. 2025,
装运港Port of Loading Пункт отгрузки: 中国 英轩工厂 Port,ChinaФабрика ENSIGN, Китай
目的港Port of Destination Пункт назначения: 哈萨克斯坦,突厥斯坦 Turkestan Port, KazakhstanРусский Тур
付款方式Payment Условия оплаты:
Free given spare parts along with the purchasing machines.
Бесплатно предоставляем запасные части вместе с приобретаемой техникой.
合同有效期Expiry Date of the Contract Срок действия договора/срок возврата аванса:
2025年5月30日 May 30th, 2025
货物所有权转移Transfer of the goods ownership Передача товара в собственность:
买方付清全部货款后,货物所有权转移给买方;如果买方没有付清全部货款,卖方保留对货物的全部所有权。
The ownership of the goods shall be transferred to the buyer after the buyer pays back the total contract value. The seller retains the full ownership of the goods if the buyer doesn't pay back the total contract value.
Передача товара в собственность Покупателю произойдет после полной оплаты Покупателем стоимости договора. Право собственности на товар сохраняется за Продавцом в случае, если Покупатель не выплачивает полную стоимость договора.
9.不可抗力Force Majeure Форс-мажор:
卖方由于罢工、火灾、地震、暴动、爆炸、政府行为等不可抗力事故,未能在合同规定期限内装货或不能交货,则不承担责任,卖方应立即以传真通知买方,如果买方提出要求,卖方应以挂号函件向买方提供由中国国际贸易促进委员会或有关机构出具的证明,证明上述事由的存在。
The Seller shall not be held responsible if they, owing to force majeure cause, such as Act of God, strike, riot, civil commotion, breakdown of machinery, fire or any other causes beyond Seller's control, fail to make delivery within the time stipulated in the Contract or cannot deliver the goods. However in such cases, the Seller shall inform the Buyer immediately by fax and if it is requested by the Buyer, shall also deliver to the Buyer by registered letter, a certificate attesting the existence of such a cause issued by the China Council for the Promotion of International Trade or by a competent authority.
Продавец не несет ответственности за события, происходящие вследствие форс-мажора, если таковые происходят: стихийные бедствия, забастовки, мятежи, гражданские волнения, выход из строя оборудования, пожар или другие события, выходящие за рамки контроля Продавца, и приведшие к нарушению сроков поставок в периоды, оговоренные Договором, либо к невозможности поставки Товара. Однако, о всех таких случаях Продавец незамедлительно информирует Покупателя по факсу и, если это требуется Покупателю, официальным письмом, справкой, подтверждающей наступление таких событий, заверенной китайским консулом по международной торговле или другим компетентным органом.
10.异议和索赔Discrepancy and Claim Несоответствия и претензии:
1外观质量和数量等可目视检查的不符或缺失买方需在货物到达目的港后10个工作日内提报卖方产品潜在缺陷买方需在货物到港后30个工作日内凭卖方认可的权威机构出具的检测报告提报卖方未经卖方同意买方不得销售或使用该类产品。
(1) The visual survey of any discrepancy or deficiency such as apparent quality and quantity should be reported to the seller within 10 working days from the date of goods arrival at the destination port, while for the latent defects of goods, an Inspection Report issued by an approved authority institution by the Seller should be sent to the Seller within 30 working days from the date of goods arrival at the destination port. The defective goods which have not been approved by the Seller should not be sold or used.
(1) Выявленные при визуальном осмотре несоответствия и дефекты, как в качестве, так и в количестве, должны быть предоставлены в форме отчета Продавцу в течение 10 рабочих дней в даты поступления товара в пункт назначения, в то время отчет по скрытым дефектам товара, выданный уполномоченным государством учреждением, должен быть отправлен Продавцу по электронной почте в течение 30 дней с даты поступления товара в пункт назначения. Оборудование с дефектами не может быть продано или использовано без разрешения Продавца.
(2) 卖方向买方提供制造商提供的所有质保。装载机质保期为提单日起24个月经销商销售日起18个月装载机开始运行起2000个工作小时以先到者为准
(2)The Seller provides the Buyer all the warranties provided by the factory-manufacturer. Wheel loader warranty period is 24 months since date of B/L, 18 months since date of sale by the dealer, 2000 working hours since the loader starts to be operatedsubject to whichever comes first.
(2) Продавец обеспечивает Покупателю все гарантии, предоставленные заводом-производителем. Гарантийный период составляет 24 месяца с даты получения предоплаты, 18 месяцев с даты продажи дилером, 2000 мото/часов с момента запуска в работу, в зависимости от того, что наступает раньше.
11.仲裁Arbitration Арбитраж:
凡因执行本合同和有关本合同所发生的一切争执,双方应协商解决,如果协商不能解决,应提交位于北京的中国国际经济贸易仲裁委员会,根据其仲裁规则进行仲裁,仲裁裁决是终局的,对双方均有约束力,除非另有规定外,仲裁费用均由败诉方负担。本合同适用中国法律。
All disputes arising from the execution of, or in connection with this Contract, shall be settled through negotiation. In case no settlement can be reached through negotiation, the case shall then be submitted to the China International Economic and Trade Arbitration Commission, Beijing, for arbitration in accordance with the Commission's Rules of Procedure. The award rendered by the Commission shall be final and binding on bothparties. The fees for arbitration shall be borne by the losing party unless otherwise awarded. This contract issigned as to Chinese laws.
Все споры, возникающие при исполнении или в связи с настоящим Контрактом, должны решаться путемпереговоров. В случае невозможности урегулирования спора путем переговоров, дело передается вКитайскую международную экономическую и торговую арбитражную комиссию, Пекин, для арбитража всоответствии с Правилами процедуры Комиссии. Решение, вынесенное Комиссией, являетсяокончательным и обязательным для обеих сторон. Арбитражные сборы несет проигравшая сторона, если не принято иное решение. Настоящий договор подписан в соответствии с законодательством Китая.
12本合同采用中英俄文书写经双方签字后生效传真件或扫描副本有效,如若中英俄文有歧义,则以中文为准。双方对本合同所有内容有保密义务,不得以任何形式泄露给第三方。任何一方在未取得对方书面同意前,无权将本合同规定之权利义务转让给第三方。本合同所有附件属于合同的组成部分,与本合同具有同等法律效力。
This appendix is made in Chinese English and Russian becomes effective as soon as it is signed by both parties. Fax copies and scanned originals of the docs hold the same force. And if any dispute or miscellaneous on language here determinate that Chinese version is predominate authentic. Both parties shall be responsible to keep all the information under this contract confident and cannot reveal to any third party in any manner. Neither party is entitled to transfer its right and obligation under this Contract to a third party before obtaining a written consent from the other party. All appendixes to the Contract shall form an integral part of the Contract and have the same effectiveness as the contract。
Настоящее приложение составлено на китайском английском и русском языках и вступает в силу с момента его подписания обеими сторонами. Факсимильные копии и сканы оригиналов документов имеют такую же силу. И если возникнет спор или разногласие по поводу языка, здесь определяется, что китайская версия является преобладающей аутентичной. Обе стороны несут ответственность за сохранение всей информации по настоящему договору в тайне и не могут раскрывать ее третьим лицам каким-либо образом. Ни одна из сторон не имеет права передавать свои права и обязательства по настоящему Контракту третьей стороне до получения письменного согласия другой стороны. Все приложения к контракту являются его неотъемлемой частью и имеют такую же силу, как и контракт.
13、卖方银行信息 The Seller's Bank Information Банковские реквизиты
本合同项下款项必须付到以下银行账户:
Payments under this contract must be paid to the following bank account:
Платежи по настоящему договору производятся по следующим банковским реквизитам:
Beneficiary Получатель: ENSIGN HEAVY INDUSTRIES CO., LTD.
Address Адрес: No.1567, Ensign Street, Economic Development Zone, Changle, Weifang, Shandong, China.
Tel: +86-536-6298882 Fax:+86-536-6298797
Bank Name Наименование банка : CHINA ZHESHANG BANK Китайский Zhe Shang Bank
Bank Address Адрес банка: NO.288 Qingchun Road,Hangzhou City,Zhejiang Province,China
№ 288 Цинчунь, город Ханчжоу, провинция Чжэцзян, Китай
Swift Code: ZJCBCN2N
Account Number: 4580000010120100081585
以上任何银行信息的变更,以卖方传真通知为准。
Any changes of the above bank information shall be subject to the seller's fax notice only.
Все изменения банковских реквизитов допускаются только при условии направления Продавцом уведомления по факсу.
卖方 买方
The Seller The Buyer
Продавец: _{{@image}} Покупатель : ________________
供方盖章

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

View File

@ -0,0 +1,13 @@
package vin.vio.usepoitl;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class UsePoiTlApplicationTests {
@Test
void contextLoads() {
}
}