docx, search keys from doc

This commit is contained in:
akulikov 2022-12-12 21:58:20 +03:00
parent 15f2180f29
commit b663824a5a
4 changed files with 133 additions and 0 deletions

View file

@ -33,11 +33,23 @@
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.19</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.1.0</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View file

@ -0,0 +1,90 @@
package ru.spcex.clearing.reports.services;
import org.apache.poi.xwpf.usermodel.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Сервис для работы с DOCX файлами
* Читает шаблон .docx и во всех текстовых элементах меняет переданные ключи на соответствующие им значения
*/
public class DOCXService {
/**
* При инициализации сохраняет все имеющиеся ключи (ищет по маске keyPattern), найденные в текстовых элементах документа
*/
private final Map<String, TextPositionOnRun> bodyElementForKey = new HashMap<>();
private final Pattern KEY_PATTERN = Pattern.compile("\\$\\{.*?}");
private final int MAX_POSITION = 128;
/**
* Инициализация шаблона
*
* @param templateFile файл шаблона
*/
public void init(File templateFile) throws IOException {
assert templateFile != null && templateFile.exists() && templateFile.isFile();
try (InputStream inputStream = new FileInputStream(templateFile)) {
XWPFDocument doc = new XWPFDocument(inputStream);
for (IBodyElement element : doc.getBodyElements()) {
if (element instanceof XWPFTable table) {
collectKeysFromTable(table);
} else if (element instanceof XWPFParagraph paragraph) {
collectKeysFromParagraph(paragraph);
}
}
System.out.println("hello");
}
}
private void collectKeysFromTable(XWPFTable srcTable) {
for (XWPFTableRow row : srcTable.getRows()) {
for (XWPFTableCell cell : row.getTableCells()) {
for (IBodyElement element : cell.getBodyElements()) {
if (element instanceof XWPFTable table) {
collectKeysFromTable(table);
} else if (element instanceof XWPFParagraph paragraph) {
collectKeysFromParagraph(paragraph);
}
}
}
}
}
private void collectKeysFromParagraph(XWPFParagraph paragraph) {
for (XWPFRun run : paragraph.getRuns()) {
try {
for (int currPos = 0; currPos < MAX_POSITION; currPos++) {
String currText = run.getText(currPos);
if (currText == null) break;
Matcher matcher = KEY_PATTERN.matcher(currText);
while (matcher.find()) {
String key = matcher.group();
bodyElementForKey.put(key, new TextPositionOnRun(run, currPos));
}
}
} catch (IndexOutOfBoundsException ignored) {
// can't get all max text position for XWPFRun
}
}
}
static class TextPositionOnRun {
XWPFRun run;
int pos;
public TextPositionOnRun(XWPFRun run, int pos) {
this.run = run;
this.pos = pos;
}
}
}

View file

@ -0,0 +1,31 @@
package ru.spcex.clearing.reports.services;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.junit.jupiter.api.Test;
import java.io.*;
class DOCXServiceTest {
@Test
public void testREC_ACTV() {
String inputFilename = "REC.ACTV_TEST.docx";
try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream(inputFilename);
InputStream testStream = getClass().getClassLoader().getResourceAsStream("1.docx");
OutputStream outputStream = new FileOutputStream("test.docx")) {
XWPFDocument templateDoc = new XWPFDocument(inputStream);
XWPFDocument testDoc = new XWPFDocument(testStream);
testDoc.getParagraphs().get(6).getRuns().get(1).setText("========АОВЛДЫАОЫВЛДОАЛЫВДАОЫВЛДАОЫВ========");
testDoc.write(outputStream);
System.out.println("h");
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void test() throws IOException {
DOCXService service = new DOCXService();
service.init(new File(getClass().getClassLoader().getResource("REC.ACTV_TEST.docx").getPath()));
System.out.println("p");
}
}