|
Создание docx подобного формата
#38622880
Ссылка:
Ссылка на сообщение:
Ссылка с названием темы:
|
|
|
|
GeometryНужна идея как можно подобное организовать с ипользованием ZipInputStream и ZipOutputStream
Программка ищет все docx и txt файлы с одинаковыми названиями (игнорируя регистр) в текущей директории, (пере-) создаёт директорию out с копиями docx файлов в которых заменены символы $ на строки из txt файлов. Если строк в txt файле меньше - оставшиеся $ будут выброшены.
MergeDocx.java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196. 197. 198. 199. 200. 201. 202. 203. 204. 205. 206. 207. 208.
package mergedocx;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.nio.file.DirectoryStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.nio.file.Files.*;
import static ru.tensor.petrov.commons.util.StringUtil.endsWith_ignoreCase;
import static ru.tensor.petrov.commons.util.StringUtil.trimEnd;
import static ru.tensor.petrov.commons.util.SystemOut.fixupWindowsConsoleEncoding;
import static ru.tensor.petrov.commons.util.SystemOut.println;
public class MergeDocx {
private static final int CHARACTER_TO_REPLACE = '$';
private static final Charset CHARSET_1251 = Charset.forName("Cp1251");
public static void main(String[] a) throws IOException {
fixupWindowsConsoleEncoding();
Path fileRoot = Paths.get(".").toRealPath();
println("Папка:\n ", fileRoot);
Map<String, PairFile> map = new HashMap<>();
try (DirectoryStream<Path> directoryStream = newDirectoryStream(fileRoot)) {
//<editor-fold defaultstate="collapsed" desc="mapping">
for (Path file : directoryStream) {
if (!isDirectory(file)) {
String nameWithMask = file.getFileName().toString();
if (endsWith_ignoreCase(nameWithMask, ".txt")) {
String name = trimEnd(nameWithMask, 4).toLowerCase();
if (map.containsKey(name)) {
map.get(name).txt = file;
} else {
map.put(name, PairFile.fromTxt(file));
}
} else if (endsWith_ignoreCase(nameWithMask, ".docx")) {
String name = trimEnd(nameWithMask, 5).toLowerCase();
if (map.containsKey(name)) {
map.get(name).docx = file;
} else {
map.put(name, PairFile.fromDocx(file));
}
}
}
}
//</editor-fold>
}
boolean hasGood = false;
ArrayList<PairFile> pairlessFiles = new ArrayList<>();
for (PairFile pair : map.values()) {
if (!pair.isComplete()) {
pairlessFiles.add(pair);
} else {
hasGood = true;
}
}
if (!pairlessFiles.isEmpty()) {
println();
if (pairlessFiles.size() == 1) {
println("У файла нет пары:");
} else {
println("У ", pairlessFiles.size(), " файлов нет пар:");
}
for (PairFile pairlessFile : pairlessFiles) {
println(" ", pairlessFile.getAName());
}
}
int cntHandled = 0, cntTotal = 0;
boolean lose = false;
if (hasGood) {
println("\n" + "Обработка: ");
Path dirOut = fileRoot.resolve("out");
if (exists(dirOut)) {
deleteDir(dirOut);
}
createDirectories(dirOut);
for (PairFile pair : map.values()) {
if (pair.isComplete()) {
println(" ", pair.txt.getFileName());
Path docxFileName = pair.docx.getFileName();
println(" ", docxFileName);
try {
MergeProccessInfo info = process(pair, dirOut.resolve(docxFileName));
//<editor-fold defaultstate="collapsed" desc="print info">
if (info.hasDocumentXml) {
if (info.isConverge()) {
println(" OK (заменено: ", info.cntLines_inTxt, ")");
} else {
lose = true;
println(" НЕ СОШЛОСЬ (txt: ", info.cntLines_inTxt, ", docx: ", info.cntSymbols_inDocx, ")");
}
} else {
lose = true;
println(" ОШИБКА: docx файл имеет не верный формат (отсутствует document.xml). Строк в txt: ", info.cntLines_inTxt);
}
//</editor-fold>
++cntHandled;
} catch (Throwable any) {
lose = true;
println(" ОШИБКА: ", any);
}
println();
}
++cntTotal;
}
}
println("Обработано ", cntHandled, " из ", cntTotal, " файлов");
println(lose ? "Были ошибки" : "Ошибок не было");
if (!pairlessFiles.isEmpty()) {
println("\n" + "Были файл(ы) не имеющие пар (", pairlessFiles.size(), ")");
}
}
private static MergeProccessInfo process(PairFile pair, Path fileOut) throws Exception {
MergeProccessInfo info = new MergeProccessInfo();
try (
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(newInputStream(pair.docx)));
ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(newOutputStream(fileOut)));
BufferedReader readerTxt = newBufferedReader((pair.txt), CHARSET_1251);
)
{
for (ZipEntry entry; (entry = zis.getNextEntry()) != null;) {
String name = entry.getName();
zos.putNextEntry(new ZipEntry(name));
if (endsWith_ignoreCase(name, "document.xml")) {
info.hasDocumentXml = true;
BufferedReader readerZipEntry = new BufferedReader(new InputStreamReader(zis, UTF_8));
BufferedWriter writerZipEntry = new BufferedWriter(new OutputStreamWriter(zos, UTF_8));
for (int ch; (ch = readerZipEntry.read()) > -1;) {
if (ch == CHARACTER_TO_REPLACE) {
info.cntSymbols_inDocx++;
String line = readerTxt.readLine();
if (line != null) {
writerZipEntry.write(line);
info.cntLines_inTxt++;
}
} else {
writerZipEntry.write(ch);
}
}
writerZipEntry.flush();
}
copy(zis, zos);
zos.closeEntry();
}
//<editor-fold defaultstate="collapsed" desc="подсчёт лишних строк в txt файле">
while (readerTxt.readLine() != null) {
info.cntLines_inTxt++;
}
//</editor-fold>
}
return info;
}
//<editor-fold defaultstate="collapsed" desc="copy">
private static final byte[] BUFFER = new byte[4096 * 1024];
private static void copy(InputStream input, OutputStream output) throws IOException {
for (int length; (length = input.read(BUFFER)) != -1;) {
output.write(BUFFER, 0, length);
}
}
//</editor-fold>
private static void deleteDir(Path dir) throws IOException {
try (DirectoryStream<Path> directoryStream = newDirectoryStream(dir)) {
for (Path path : directoryStream) {
if (isDirectory(path)) {
deleteDir(dir);
} else {
delete(path);
}
}
}
}
}
MergeProccessInfo.java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
package mergedocx;
public class MergeProccessInfo {
public int cntLines_inTxt, cntSymbols_inDocx;
public boolean hasDocumentXml;
public boolean isConverge() {
return cntLines_inTxt == cntSymbols_inDocx;
}
}
PairFile.java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36.
package mergedocx;
import java.nio.file.Path;
public class PairFile {
public Path txt, docx;
private PairFile() {}
public static PairFile fromTxt(Path txt) {
PairFile pairFile = new PairFile();
pairFile.txt = txt;
return pairFile;
}
public static PairFile fromDocx(Path docx) {
PairFile pairFile = new PairFile();
pairFile.docx = docx;
return pairFile;
}
public boolean isComplete() {
return txt != null && docx != null;
}
public String getAName() {
if (txt != null) {
return txt.getFileName().toString();
} else if (docx != null) {
return docx.getFileName().toString();
} else {
return "";
}
}
}
|
|
|