docx, search keys from doc
This commit is contained in:
parent
15f2180f29
commit
b663824a5a
4 changed files with 133 additions and 0 deletions
|
|
@ -33,11 +33,23 @@
|
||||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||||
<artifactId>jackson-dataformat-xml</artifactId>
|
<artifactId>jackson-dataformat-xml</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.thoughtworks.xstream</groupId>
|
<groupId>com.thoughtworks.xstream</groupId>
|
||||||
<artifactId>xstream</artifactId>
|
<artifactId>xstream</artifactId>
|
||||||
<version>1.4.19</version>
|
<version>1.4.19</version>
|
||||||
</dependency>
|
</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>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
Loading…
Add table
Reference in a new issue