Mercurial > mercurial > hgweb_kaigo.hg.cgi
comparison Nk/nk.go @ 0:aaaa401818a1 draft
first commit.
author | pyon <pyon@macmini> |
---|---|
date | Mon, 24 May 2021 21:32:58 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:aaaa401818a1 |
---|---|
1 /* | |
2 nk.go: Nintei Kekka | |
3 | |
4 Last Change: 2020-10-16 金 14:27:50. | |
5 */ | |
6 | |
7 package main | |
8 | |
9 /* | |
10 #cgo LDFLAGS: -L. -lxdwapi -static | |
11 #include <stdio.h> | |
12 #include <stdlib.h> | |
13 #include <string.h> | |
14 #include <io.h> | |
15 #include <windows.h> | |
16 #include <xdw_api.h> | |
17 #include <xdwapian.h> | |
18 | |
19 #define MAXCOL 1024 | |
20 #define MAXLINE 9999 | |
21 #define BLOCKSZ 128 | |
22 | |
23 int xdwpages(const char* file) { | |
24 char in_path[_MAX_PATH]; | |
25 _fullpath(in_path, file, _MAX_PATH); | |
26 | |
27 XDW_DOCUMENT_HANDLE h = NULL; // 文書ハンドルを開く | |
28 XDW_OPEN_MODE_EX mode = {sizeof(XDW_OPEN_MODE_EX), XDW_OPEN_READONLY, XDW_AUTH_NODIALOGUE}; | |
29 if (XDW_OpenDocumentHandle(in_path, &h, (XDW_OPEN_MODE*)&mode)) { | |
30 printf("Error: cannot open %s\n", file); | |
31 return -1; | |
32 } | |
33 | |
34 XDW_DOCUMENT_INFO info = {sizeof(XDW_DOCUMENT_INFO), 0, 0, 0}; // 総ページ数を得る | |
35 XDW_GetDocumentInformation(h, &info); | |
36 int nPage = info.nPages; | |
37 | |
38 XDW_CloseDocumentHandle(h, NULL); // 文書ハンドルを閉じる | |
39 | |
40 return nPage; | |
41 } | |
42 | |
43 char* xdw2txt(const char* file) { | |
44 char in_path[_MAX_PATH]; | |
45 _fullpath(in_path, file, _MAX_PATH); | |
46 | |
47 XDW_DOCUMENT_HANDLE h = NULL; // 文書ハンドルを開く | |
48 XDW_OPEN_MODE_EX mode = {sizeof(XDW_OPEN_MODE_EX), XDW_OPEN_READONLY, XDW_AUTH_NODIALOGUE}; | |
49 if (XDW_OpenDocumentHandle(in_path, &h, (XDW_OPEN_MODE*)&mode)) { | |
50 printf("Error: cannot open %s\n", file); | |
51 return NULL; | |
52 } | |
53 | |
54 XDW_DOCUMENT_INFO info = {sizeof(XDW_DOCUMENT_INFO), 0, 0, 0}; // 総ページ数を得る | |
55 XDW_GetDocumentInformation(h, &info); | |
56 int nPage = info.nPages; | |
57 | |
58 // メイン処理 | |
59 char *lpszvalue, *all_lpszvalue; | |
60 long datasize[9999]; | |
61 for (int i=1; i<=nPage; i++) { | |
62 datasize[i] = XDW_GetPageTextToMemory(h, i, NULL, 0, NULL); | |
63 datasize[0] += datasize[i]; | |
64 } | |
65 datasize[0] += nPage - 1; // for "\n" | |
66 all_lpszvalue = (char*)malloc(sizeof(char)*datasize[0]); | |
67 all_lpszvalue[0] = '\0'; | |
68 for (int i=1; i<=nPage; i++) { | |
69 if (i<nPage) datasize[i]++; // for "\n" | |
70 lpszvalue = (char*)malloc(sizeof(char)*(datasize[i])); | |
71 XDW_GetPageTextToMemory(h, i, lpszvalue, datasize[i], NULL); | |
72 strcat(all_lpszvalue, lpszvalue); | |
73 if (i<nPage) strcat(all_lpszvalue, "\n"); | |
74 free(lpszvalue); | |
75 } | |
76 | |
77 XDW_CloseDocumentHandle(h, NULL); // 文書ハンドルを閉じる | |
78 return all_lpszvalue; | |
79 } | |
80 | |
81 int xdwpush(const char* file1, const char* file2) { | |
82 char in_path[_MAX_PATH], add_path[_MAX_PATH]; | |
83 _fullpath(in_path, file1, _MAX_PATH); | |
84 _fullpath(add_path, file2, _MAX_PATH); | |
85 | |
86 XDW_DOCUMENT_HANDLE h = NULL; | |
87 XDW_OPEN_MODE_EX mode = {sizeof(XDW_OPEN_MODE_EX), XDW_OPEN_UPDATE, XDW_AUTH_NODIALOGUE}; | |
88 | |
89 int api_result = XDW_OpenDocumentHandle(in_path, &h, (XDW_OPEN_MODE*)&mode); | |
90 if (api_result < 0) return api_result; | |
91 | |
92 XDW_DOCUMENT_INFO info = {sizeof(XDW_DOCUMENT_INFO), 0, 0, 0}; | |
93 XDW_GetDocumentInformation(h, &info); | |
94 int last_page = info.nPages; | |
95 | |
96 api_result = XDW_InsertDocument(h, last_page+1, add_path, NULL); | |
97 if (api_result < 0) api_result; | |
98 | |
99 XDW_SaveDocument(h, NULL); | |
100 XDW_CloseDocumentHandle(h, NULL); | |
101 | |
102 return (api_result >= 0); | |
103 } | |
104 | |
105 int xdwhbaddatn(const char* file, char* atnlist) { | |
106 char in_path[_MAX_PATH]; | |
107 _fullpath(in_path, file, _MAX_PATH); | |
108 | |
109 XDW_DOCUMENT_HANDLE h = NULL; | |
110 XDW_OPEN_MODE_EX mode = {sizeof(XDW_OPEN_MODE_EX), XDW_OPEN_UPDATE, XDW_AUTH_NODIALOGUE}; | |
111 | |
112 int api_result = XDW_OpenDocumentHandle(in_path, &h, (XDW_OPEN_MODE*)&mode); | |
113 if (api_result < 0) return api_result; | |
114 | |
115 XDW_DOCUMENT_INFO info = {sizeof(XDW_DOCUMENT_INFO), 0, 0, 0}; | |
116 XDW_GetDocumentInformation(h, &info); | |
117 | |
118 char *str, *token; | |
119 char *saveptr1, *saveptr2; | |
120 int x, y, sz, tr; | |
121 char *s; | |
122 | |
123 for (str = atnlist; ; str = NULL) { | |
124 token = strtok_r(str, ":", &saveptr1); | |
125 if (token == NULL) break; | |
126 //printf("%s\n", token); | |
127 | |
128 // atn.X, atn.Y, atn.Sz, tr, atn.Txt | |
129 x = atoi(strtok_r(token, ",", &saveptr2)); | |
130 y = atoi(strtok_r(NULL , ",", &saveptr2)); | |
131 sz = atoi(strtok_r(NULL, ",", &saveptr2)); | |
132 tr = atoi(strtok_r(NULL, ",", &saveptr2)); | |
133 s = strtok_r(NULL, ",", &saveptr2); | |
134 //printf("x=%d y=%d txt=%s sz=%d tr=%d\n", x, y, s, sz, tr); | |
135 | |
136 for (int i = 0; i < info.nPages; i++ ) { | |
137 XDW_ANNOTATION_HANDLE annoation; | |
138 int api_result = XDW_AddAnnotation(h, XDW_AID_TEXT, i + 1, x, y, NULL, &annoation, NULL); | |
139 | |
140 if (api_result < 0) return api_result; | |
141 | |
142 api_result = XDW_SetAnnotationAttribute(h, annoation, XDW_ATN_Text, XDW_ATYPE_STRING, s, 0, NULL); | |
143 api_result = XDW_SetAnnotationAttribute(h, annoation, XDW_ATN_FontSize, XDW_ATYPE_INT, (char*)&sz, 0, NULL); | |
144 | |
145 if (tr) { | |
146 int color = XDW_COLOR_NONE; | |
147 api_result = XDW_SetAnnotationAttribute(h, annoation, XDW_ATN_BackColor, XDW_ATYPE_INT, (char*)&color, 0, NULL); | |
148 } | |
149 } | |
150 } | |
151 | |
152 XDW_SaveDocument(h, NULL); | |
153 XDW_CloseDocumentHandle(h, NULL); | |
154 | |
155 return 0; | |
156 } | |
157 | |
158 int xdwsort(const char* file, const char* sorted, const char* order, const char* workdir, const char* prefix) { | |
159 char buf[MAXCOL]; | |
160 | |
161 // メモリ確保 | |
162 char *sl = (char*)malloc(MAXLINE * sizeof(char) * MAXCOL); | |
163 if (sl == NULL) return -1; | |
164 | |
165 int slN = 0; | |
166 char *p; | |
167 p = strtok(order, ":"); | |
168 strncpy(&sl[slN * MAXCOL], p, MAXCOL); | |
169 slN++; | |
170 | |
171 while (p = strtok(NULL, ":")) { | |
172 strncpy(&sl[slN * MAXCOL], p, MAXCOL); | |
173 slN++; | |
174 } | |
175 | |
176 //for (int j = 0; j < slN; j++) printf("%d : %s\n", j, &sl[j * MAXCOL]); | |
177 //return 0; | |
178 | |
179 // 重み付け = 並び順 | |
180 char in_path[_MAX_PATH]; | |
181 _fullpath(in_path, file, _MAX_PATH); | |
182 | |
183 XDW_DOCUMENT_HANDLE h = NULL; | |
184 XDW_OPEN_MODE_EX mode = {sizeof(XDW_OPEN_MODE_EX), XDW_OPEN_READONLY, XDW_AUTH_NODIALOGUE}; | |
185 | |
186 int api_result = XDW_OpenDocumentHandle(in_path, &h, (XDW_OPEN_MODE*)&mode); | |
187 if (api_result < 0) return api_result; | |
188 | |
189 XDW_DOCUMENT_INFO info = {sizeof(XDW_DOCUMENT_INFO), 0, 0, 0}; | |
190 XDW_GetDocumentInformation(h, &info); | |
191 int last_page = info.nPages; | |
192 | |
193 int *table = (int*)malloc(sizeof(int) * last_page); | |
194 for (int p = 0; p < last_page; p++) *(table + p) = 9999; | |
195 | |
196 int index = 0; | |
197 XDW_FOUND_HANDLE pFoundHandle = NULL; | |
198 for (int i = 0; i < slN; i++) { | |
199 for (int p = 0; p < last_page; p++) { | |
200 if (*(table + p) != 9999) continue; | |
201 | |
202 api_result = XDW_FindTextInPage(h, p + 1, &sl[i * MAXCOL], NULL, &pFoundHandle, NULL); | |
203 if (api_result < 0) return api_result; | |
204 | |
205 if (pFoundHandle != NULL) { | |
206 *(table + p) = ++index; | |
207 pFoundHandle = NULL; | |
208 } | |
209 } | |
210 } | |
211 free(sl); | |
212 | |
213 for (int p = 0; p < last_page; p++) { | |
214 if (*(table + p) == 9999) *(table + p) = ++index; | |
215 | |
216 sprintf(buf, "%s/%s_%04d.xdw", workdir, prefix, *(table + p)); | |
217 _fullpath(in_path, buf, _MAX_PATH); | |
218 | |
219 api_result = XDW_GetPage(h, p + 1, in_path, NULL); | |
220 if (api_result < 0) return api_result; | |
221 } | |
222 free(table); | |
223 XDW_CloseDocumentHandle(h, NULL); | |
224 | |
225 // ブロック処理 | |
226 char *blk_path = (char*)malloc(BLOCKSZ * sizeof(char) * _MAX_PATH); | |
227 const char **blk_path_addr = (const char**)malloc((last_page / BLOCKSZ + 1) * sizeof(char*) * _MAX_PATH); | |
228 | |
229 int bn = 0; | |
230 for (int p = 0, m = 0; p < last_page; p++) { | |
231 m = p % BLOCKSZ; | |
232 | |
233 if (m == 0 && p > 0) { | |
234 sprintf(buf, "%s/%s_b%04d.xdw", workdir, prefix, ++bn); | |
235 _fullpath(in_path, buf, _MAX_PATH); | |
236 | |
237 api_result = XDW_MergeXdwFiles(blk_path_addr, BLOCKSZ, in_path, NULL); | |
238 if (api_result < 0) return api_result; | |
239 } | |
240 | |
241 sprintf(buf, "%s/%s_%04d.xdw", workdir, prefix, p + 1); | |
242 _fullpath(in_path, buf, _MAX_PATH); | |
243 | |
244 strncpy(&blk_path[m * _MAX_PATH], in_path, _MAX_PATH); | |
245 | |
246 blk_path_addr[m] = &blk_path[m * _MAX_PATH]; | |
247 } | |
248 | |
249 sprintf(buf, "%s/%s_b%04d.xdw", workdir, prefix, ++bn); | |
250 _fullpath(in_path, buf, _MAX_PATH); | |
251 | |
252 int mod = last_page % BLOCKSZ; | |
253 if (mod == 0) mod = BLOCKSZ; | |
254 | |
255 api_result = XDW_MergeXdwFiles(blk_path_addr, mod, in_path, NULL); | |
256 if (api_result < 0) return api_result; | |
257 | |
258 for (int b = 0; b < bn; b++) { | |
259 sprintf(buf, "%s/%s_b%04d.xdw", workdir, prefix, b + 1); | |
260 | |
261 _fullpath(in_path, buf, _MAX_PATH); | |
262 strncpy(&blk_path[b * _MAX_PATH], in_path, _MAX_PATH); | |
263 | |
264 blk_path_addr[b] = &blk_path[b * _MAX_PATH]; | |
265 } | |
266 | |
267 _fullpath(in_path, sorted, _MAX_PATH); | |
268 | |
269 api_result = XDW_MergeXdwFiles(blk_path_addr, bn, in_path, NULL); | |
270 if (api_result < 0) return api_result; | |
271 | |
272 free(blk_path); | |
273 free(blk_path_addr); | |
274 | |
275 return 0; | |
276 } | |
277 | |
278 int xdwerase(const char* in_file, const char* ktxt, const char* htxt) { | |
279 int x = 20000; | |
280 int y = 3685; | |
281 int sz = 480; | |
282 | |
283 char in_path[_MAX_PATH]; | |
284 _fullpath(in_path, in_file, _MAX_PATH); | |
285 | |
286 XDW_DOCUMENT_HANDLE h = NULL; | |
287 XDW_OPEN_MODE_EX mode = {sizeof(XDW_OPEN_MODE_EX), XDW_OPEN_UPDATE, XDW_AUTH_NODIALOGUE}; | |
288 | |
289 int api_result = XDW_OpenDocumentHandle(in_path, &h, (XDW_OPEN_MODE*)&mode); | |
290 if (api_result < 0) return api_result; | |
291 | |
292 XDW_DOCUMENT_INFO info = {sizeof(XDW_DOCUMENT_INFO), 0, 0, 0}; | |
293 XDW_GetDocumentInformation(h, &info); | |
294 | |
295 XDW_FOUND_HANDLE pFoundHandle = NULL; | |
296 for (int i = 0; i < info.nPages; i++) { | |
297 api_result = XDW_FindTextInPage(h, i + 1, htxt, NULL, &pFoundHandle, NULL); | |
298 if (pFoundHandle == NULL) continue; | |
299 | |
300 api_result = XDW_FindTextInPage(h, i + 1, ktxt, NULL, &pFoundHandle, NULL); | |
301 if (pFoundHandle == NULL) continue; | |
302 | |
303 XDW_ANNOTATION_HANDLE annoation; | |
304 int api_result = XDW_AddAnnotation(h, XDW_AID_TEXT, i + 1, x, y, NULL, &annoation, NULL); | |
305 if (api_result < 0) return api_result; | |
306 | |
307 api_result = XDW_SetAnnotationAttribute(h, annoation, XDW_ATN_Text, XDW_ATYPE_STRING, " ", 0, NULL); | |
308 api_result = XDW_SetAnnotationAttribute(h, annoation, XDW_ATN_FontSize, XDW_ATYPE_INT, (char*)&sz, 0, NULL); | |
309 } | |
310 | |
311 XDW_SaveDocument(h, NULL); | |
312 XDW_CloseDocumentHandle(h, NULL); | |
313 | |
314 return 0; | |
315 } | |
316 | |
317 int xdw2pdf(const char* xdwfile, const char* pdffile) { | |
318 char in_path[_MAX_PATH], out_path[_MAX_PATH]; | |
319 _fullpath(in_path, xdwfile, _MAX_PATH); | |
320 _fullpath(out_path, pdffile, _MAX_PATH); | |
321 | |
322 remove(out_path); | |
323 int api_result = 0; | |
324 | |
325 XDW_DOCUMENT_HANDLE h = NULL; | |
326 XDW_OPEN_MODE_EX mode = {sizeof(XDW_OPEN_MODE_EX), XDW_OPEN_READONLY, XDW_AUTH_NODIALOGUE}; | |
327 | |
328 api_result = XDW_OpenDocumentHandle(in_path, &h, (XDW_OPEN_MODE*)&mode); | |
329 if (api_result < 0) return api_result; | |
330 | |
331 XDW_DOCUMENT_INFO info = {sizeof(XDW_DOCUMENT_INFO), 0, 0, 0}; | |
332 XDW_GetDocumentInformation(h, &info); | |
333 | |
334 XDW_IMAGE_OPTION_PDF pdf = { | |
335 sizeof(XDW_IMAGE_OPTION_PDF), | |
336 XDW_COMPRESS_MRC_NORMAL, | |
337 XDW_CONVERT_MRC_OS, | |
338 info.nPages | |
339 }; | |
340 | |
341 XDW_IMAGE_OPTION_EX ex = { | |
342 sizeof(XDW_IMAGE_OPTION_EX), | |
343 600, // dpi | |
344 XDW_IMAGE_MONO_HIGHQUALITY, | |
345 XDW_IMAGE_PDF, | |
346 &pdf | |
347 }; | |
348 | |
349 api_result = XDW_ConvertPageToImageFile(h, 1, out_path, (XDW_IMAGE_OPTION*)&ex); | |
350 | |
351 XDW_SaveDocument(h, NULL); | |
352 XDW_CloseDocumentHandle(h, NULL); | |
353 | |
354 return 0; | |
355 } | |
356 | |
357 int xdwopt(const char* in, const char* out) { | |
358 char in_path[_MAX_PATH], out_path[_MAX_PATH]; | |
359 _fullpath(in_path, in, _MAX_PATH); | |
360 _fullpath(out_path, out, _MAX_PATH); | |
361 | |
362 int api_result = XDW_OptimizeDocument(in_path, out_path, NULL); | |
363 return (api_result >= 0); | |
364 } | |
365 */ | |
366 import "C" | |
367 | |
368 import ( | |
369 "bufio" | |
370 "encoding/json" | |
371 "fmt" | |
372 "flag" | |
373 "io/ioutil" | |
374 "log" | |
375 "os" | |
376 "os/exec" | |
377 "path/filepath" | |
378 "regexp" | |
379 "sort" | |
380 "strings" | |
381 "time" | |
382 | |
383 "golang.org/x/text/encoding/japanese" | |
384 "golang.org/x/text/transform" | |
385 ) | |
386 | |
387 var ( | |
388 ver = "0.3" | |
389 | |
390 flg_hb int | |
391 flg_time bool | |
392 flg_log bool | |
393 flg_debug bool | |
394 flg_clean bool | |
395 | |
396 confjson = "nk.json" | |
397 logfile = "nk.log" | |
398 hhscsv = "hhsdb.csv" | |
399 tmpdir string | |
400 tmpprefix = "nktemp_" | |
401 inputdir = "input" | |
402 outputdir = "output" | |
403 outcsv = "out.csv" | |
404 | |
405 start time.Time | |
406 | |
407 hb string // 発番 | |
408 fw, hs, kt = "", "", "kttemp.xdw" // 負担割合証, 被保険者証, 結果通知 | |
409 | |
410 step, totalstep = 1, 14 | |
411 ) | |
412 | |
413 type Annotation struct { | |
414 X, Y int | |
415 Sz int | |
416 Tr bool | |
417 Txt string | |
418 } | |
419 | |
420 type Config struct { | |
421 Atns []Annotation | |
422 Kyotaku []string | |
423 } | |
424 | |
425 func (c *Config) ProcessTemplate() { | |
426 today := time.Now().Format("令和 r 年 1 月 2 日") | |
427 y := time.Now().Year() - 2018 | |
428 if y == 1 { | |
429 today = strings.ReplaceAll(today, "r", "元") | |
430 } else { | |
431 today = strings.ReplaceAll(today, "r", fmt.Sprintf("%d", y)) | |
432 } | |
433 | |
434 var atns []Annotation | |
435 for _, atn := range c.Atns { | |
436 s := atn.Txt | |
437 if atn.Txt == "date" { | |
438 s = today | |
439 } | |
440 if strings.ContainsAny(atn.Txt, "hb") { | |
441 s = strings.ReplaceAll(atn.Txt, "hb", hb) | |
442 } | |
443 atns = append(atns, Annotation{atn.X, atn.Y, atn.Sz, atn.Tr, s}) | |
444 } | |
445 c.Atns = atns | |
446 } | |
447 | |
448 func (c *Config) KyotakuList() []string { | |
449 return c.Kyotaku | |
450 } | |
451 | |
452 func (c *Config) AnnotationList() (al []string) { | |
453 for _, atn := range c.Atns { | |
454 tr := 0 | |
455 if atn.Tr { | |
456 tr = 1 | |
457 } | |
458 s := fmt.Sprintf("%d,%d,%d,%d,%s", atn.X, atn.Y, atn.Sz, tr, atn.Txt) | |
459 al = append(al, s) | |
460 } | |
461 return | |
462 } | |
463 | |
464 func init() { | |
465 /* INITIALIZE FLAGS */ | |
466 flag.IntVar(&flg_hb, "b", 0, "set hatsuban") | |
467 flag.BoolVar(&flg_time, "t", false, "print time") | |
468 flag.BoolVar(&flg_log, "l", false, "save log") | |
469 flag.BoolVar(&flg_debug, "d", false, "print data for debug") | |
470 flag.BoolVar(&flg_clean, "c", false, "clean temporary directory & exit") | |
471 | |
472 /* CREAN OUTPUT-FILE & TEMP-FILE */ | |
473 if err := os.RemoveAll(outputdir); err != nil { | |
474 log.Fatal(err) | |
475 } | |
476 os.Remove(logfile) | |
477 | |
478 /* PREPARATE OUTPUT-DIR & TEMP-DIR */ | |
479 if err := os.Mkdir(outputdir, 0755); err != nil { | |
480 log.Fatal(err) | |
481 } | |
482 | |
483 var err error | |
484 tmpdir, err = ioutil.TempDir(".", tmpprefix) | |
485 if err != nil { | |
486 log.Fatal(err) | |
487 } | |
488 logfile = filepath.Join(tmpdir, logfile) | |
489 kt = filepath.Join(tmpdir, kt) | |
490 } | |
491 | |
492 func main() { | |
493 flag.Parse() | |
494 | |
495 /* CLEAN TEMPORARY DIRECTORY */ | |
496 if flg_clean { | |
497 files, err := ioutil.ReadDir(".") | |
498 if err != nil { | |
499 log.Fatal(err) | |
500 } | |
501 for _, file := range files { | |
502 if strings.HasPrefix(file.Name(), tmpprefix) { | |
503 if err := os.RemoveAll(file.Name()); err != nil { | |
504 log.Fatal(err) | |
505 } | |
506 } | |
507 } | |
508 os.Exit(0) | |
509 } | |
510 | |
511 /* PRINT HEADER */ | |
512 fmt.Println("=======================================") | |
513 fmt.Println(" 被保険者証と結果通知と負担割合証を... ") | |
514 fmt.Printf(" - nk [ver %s] -\n", ver) | |
515 fmt.Println("=======================================\n") | |
516 | |
517 /* USER INPUT */ | |
518 hb = fmt.Sprintf("%d", flg_hb) | |
519 if flg_hb == 0 { | |
520 fmt.Print("発番 > ") | |
521 fmt.Scan(&hb) | |
522 } | |
523 | |
524 start = time.Now() | |
525 | |
526 /* READ CONFIG FROM JSON */ | |
527 print_step("設定読込み") | |
528 conf, err := read_conf(confjson) | |
529 if err != nil { | |
530 log.Fatal(err) | |
531 } | |
532 conf.ProcessTemplate() | |
533 step_start := print_time(start) | |
534 | |
535 /* CHECK INPUT-FILE */ | |
536 print_step("入力ファイルのチェック") | |
537 files, err := ioutil.ReadDir(inputdir) | |
538 if err != nil { | |
539 log.Fatal(err) | |
540 } | |
541 | |
542 var kts []string | |
543 for _, file := range files { | |
544 if strings.HasSuffix(file.Name(), ".xdw") { | |
545 print_debug([]string{file.Name()}) | |
546 switch file.Name()[0:8] { | |
547 case "KBPV016G": | |
548 fw = filepath.Join(inputdir, file.Name()) | |
549 case "KBPG316G": | |
550 hs = filepath.Join(inputdir, file.Name()) | |
551 case "KBPG206G", "KBPG706G": | |
552 f := filepath.Join(inputdir, file.Name()) | |
553 kts = append(kts, f) | |
554 } | |
555 } | |
556 } | |
557 | |
558 fmt.Println() | |
559 fmt.Printf(" 負担割合証ファイル = %s\n", fw) | |
560 fmt.Printf(" 被保険者証ファイル = %s\n", hs) | |
561 fmt.Print(" 結果通知ファイル =") | |
562 for _, f := range kts { | |
563 fmt.Printf(" %s", f) | |
564 } | |
565 fmt.Println() | |
566 if fw == "" || hs == "" || len(kts) == 0 { | |
567 fmt.Fprintf(os.Stderr, "Input file is wrong.\n") | |
568 os.Exit(1) | |
569 } | |
570 | |
571 bytes, err := ioutil.ReadFile(hhscsv) | |
572 if err != nil { | |
573 log.Fatal(err) | |
574 } | |
575 hash_hhs := make(map[string]string) // 被保険者氏名のハッシュ | |
576 r := strings.NewReader(string(bytes)) | |
577 tr := transform.NewReader(r, japanese.ShiftJIS.NewDecoder()) | |
578 buf := bufio.NewScanner(tr) | |
579 for buf.Scan() { | |
580 records := strings.Split(buf.Text(), ",") | |
581 hash_hhs[records[0]] = records[2] | |
582 } | |
583 fmt.Printf(" 被保険者ファイル = %s\n", hhscsv) | |
584 | |
585 step_start = print_time(step_start) | |
586 | |
587 /* CONCATNATE INPUT-FILE */ | |
588 print_step("結果通知ファイルの連結") | |
589 b, err := ioutil.ReadFile(kts[0]) | |
590 if err != nil { | |
591 log.Fatal(err) | |
592 } | |
593 if err = ioutil.WriteFile(kt, b, 0644); err != nil { | |
594 log.Fatal(err) | |
595 } | |
596 if len(kts) > 1 { | |
597 pp := 0 | |
598 fmt.Println() | |
599 for _, file := range kts { | |
600 p, _ := C.xdwpages(C.CString(file)) | |
601 fmt.Printf(" %s\t= %d ページ\n", file, int(p)) | |
602 pp += int(p) | |
603 } | |
604 fmt.Printf(" 合計\t= %d ページ\n", pp) | |
605 for _, file := range kts[1:] { | |
606 C.xdwpush(C.CString(kt), C.CString(file)) | |
607 } | |
608 } | |
609 step_start = print_time(step_start) | |
610 | |
611 /* MAKE SORT-TABEL */ | |
612 print_step("並び順の決定") | |
613 | |
614 re_hhs := regexp.MustCompile(`05((2126)|(2159)|(4346))0[1238]\d{8}`) | |
615 re_kaigo := regexp.MustCompile(`要((介護)|(支援)).`) | |
616 | |
617 hash_fw := make(map[string]int) // 負担割合証発行者のハッシュ | |
618 for _, t := range xdw2txt(fw) { | |
619 hash_fw[re_hhs.FindString(t)]++ | |
620 print_debug([]string{re_hhs.FindString(t)}) | |
621 } | |
622 | |
623 kyotaku := conf.KyotakuList() | |
624 | |
625 hash_kaigo := make(map[string]string) // 被保険者証発行者の要介護度のハッシュ | |
626 hash_kyotaku := make(map[string]string) // 被保険者証発行者の居宅介護支援事業所のハッシュ | |
627 var sorttable []string | |
628 for _, t := range xdw2txt(hs) { | |
629 h := re_hhs.FindString(t) | |
630 hash_kaigo[h] = re_kaigo.FindString(t) | |
631 for _, k := range kyotaku { | |
632 if strings.Contains(t, k) { | |
633 hash_kyotaku[h] = k | |
634 } | |
635 } | |
636 key := make_sort_key(hash_fw[h], re_kaigo.FindString(t), h) | |
637 s := fmt.Sprintf("%s#%d:%s:%s#%s", key, hash_fw[h], re_kaigo.FindString(t), hash_kyotaku[h], h) | |
638 sorttable = append(sorttable, s) | |
639 } | |
640 //sort.Sort(sort.Reverse(sort.StringSlice(sorttable))) | |
641 sort.Sort(sort.StringSlice(sorttable)) | |
642 print_debug(sorttable) | |
643 step_start = print_time(step_start) | |
644 | |
645 /* DO SORT */ | |
646 order := "" | |
647 for _, s := range sorttable { | |
648 t := strings.Split(s, "#") | |
649 order += ":" + t[len(t)-1][6:] | |
650 } | |
651 order = strings.Replace(order, ":", "", 1) | |
652 | |
653 print_step("被保険者証並び替え") | |
654 hs_sorted := filepath.Join(tmpdir, "hs.xdw") | |
655 C.xdwsort(C.CString(hs), C.CString(hs_sorted), C.CString(order), C.CString(tmpdir), C.CString("hs")) | |
656 step_start = print_time(step_start) | |
657 | |
658 print_step("負担割合証並び替え") | |
659 fw_sorted := filepath.Join(tmpdir, "fw.xdw") | |
660 C.xdwsort(C.CString(fw), C.CString(fw_sorted), C.CString(order), C.CString(tmpdir), C.CString("fw")) | |
661 step_start = print_time(step_start) | |
662 | |
663 print_step("結果通知並び替え") | |
664 kt_sorted := filepath.Join(tmpdir, "kt.xdw") | |
665 C.xdwsort(C.CString(kt), C.CString(kt_sorted), C.CString(order), C.CString(tmpdir), C.CString("kt")) | |
666 step_start = print_time(step_start) | |
667 | |
668 /* ADD HATSUBAN */ | |
669 print_step("発番印字") | |
670 al := strings.Join(conf.AnnotationList(), ":") | |
671 al, _, _ = transform.String(japanese.ShiftJIS.NewEncoder(), al) | |
672 C.xdwhbaddatn(C.CString(kt_sorted), C.CString(al)) | |
673 step_start = print_time(step_start) | |
674 | |
675 /* ERASE HOUKATSU */ | |
676 print_step("包括除去") | |
677 ktxt, _, _ := transform.String(japanese.ShiftJIS.NewEncoder(), "要介護") | |
678 htxt, _, _ := transform.String(japanese.ShiftJIS.NewEncoder(), "包括支援センター") | |
679 C.xdwerase(C.CString(hs_sorted), C.CString(ktxt), C.CString(htxt)) | |
680 step_start = print_time(step_start) | |
681 | |
682 /* OPTIMIZE OUTPUT-FILE */ | |
683 print_step("最適化") | |
684 hs_opt := filepath.Join(outputdir, "hs.xdw") | |
685 C.xdwopt(C.CString(hs_sorted), C.CString(hs_opt)) | |
686 fw_opt := filepath.Join(outputdir, "fw.xdw") | |
687 C.xdwopt(C.CString(fw_sorted), C.CString(fw_opt)) | |
688 kt_opt := filepath.Join(outputdir, "kt.xdw") | |
689 C.xdwopt(C.CString(kt_sorted), C.CString(kt_opt)) | |
690 step_start = print_time(step_start) | |
691 | |
692 /* OUTPUT CSV */ | |
693 print_step("CSV出力") | |
694 outcsv = filepath.Join(outputdir, outcsv) | |
695 fcsv, err := os.OpenFile(outcsv, os.O_RDWR|os.O_CREATE, 0644) | |
696 if err != nil { | |
697 log.Fatal(err) | |
698 } | |
699 for i, s := range sorttable { | |
700 t := strings.Split(s, "#") | |
701 u := strings.ReplaceAll(t[1], ":", ",") | |
702 u, _, _ = transform.String(japanese.ShiftJIS.NewEncoder(), u) | |
703 c := t[2][0:6] | |
704 h := t[2][6:16] | |
705 n, _, _ := transform.String(japanese.ShiftJIS.NewEncoder(), hash_hhs[h]) | |
706 // seq, city, hno, name, kaigo, fw, kyotaku | |
707 fmt.Fprintf(fcsv, "%04d,%s,%s,%s,%s\n", i + 1, c, h, n, u) | |
708 } | |
709 if err := fcsv.Close(); err != nil { | |
710 log.Fatal(err) | |
711 } | |
712 step_start = print_time(step_start) | |
713 | |
714 /* PDF */ | |
715 print_step("負担割合証割付PDF作成") | |
716 fwpdf := filepath.Join(tmpdir, "fw.pdf") | |
717 C.xdw2pdf(C.CString(fw_opt), C.CString(fwpdf)) // 2min | |
718 step_start = print_time(step_start) | |
719 | |
720 print_step("負担割合証PDF割付") | |
721 fw4pdf := filepath.Join(outputdir, "fw4.pdf") | |
722 cmd := exec.Command("fw4.exe", fwpdf, fw4pdf, tmpdir) | |
723 if err := cmd.Run(); err != nil { | |
724 log.Fatal(err) | |
725 } | |
726 step_start = print_time(step_start) | |
727 | |
728 print_step("終了") | |
729 step_start = print_time(step_start) | |
730 | |
731 /* REMOVE TEMP-FILE */ | |
732 if flg_log { | |
733 logfile2 := filepath.Join(".", strings.Replace(logfile, tmpdir, "", 1)) | |
734 os.Link(logfile, logfile2) | |
735 } | |
736 | |
737 if !flg_debug { | |
738 if err := os.RemoveAll(tmpdir); err != nil { | |
739 log.Fatal(err) | |
740 } | |
741 } | |
742 } | |
743 | |
744 func make_sort_key(fw int, kaigo, h string) string { | |
745 key := fmt.Sprintf("%d:", 9 - fw) | |
746 if strings.HasPrefix(kaigo, "要支援") { | |
747 key += "1" | |
748 } | |
749 if strings.HasPrefix(kaigo, "要介護") { | |
750 key += "2" | |
751 } | |
752 switch { | |
753 case strings.HasSuffix(kaigo, "1"): | |
754 key += "1:" | |
755 case strings.HasSuffix(kaigo, "2"): | |
756 key += "2:" | |
757 case strings.HasSuffix(kaigo, "3"): | |
758 key += "3:" | |
759 case strings.HasSuffix(kaigo, "4"): | |
760 key += "4:" | |
761 case strings.HasSuffix(kaigo, "5"): | |
762 key += "5:" | |
763 default: | |
764 key += "00:" | |
765 } | |
766 return key + h | |
767 } | |
768 | |
769 func xdw2txt(file string) (txt []string) { | |
770 s := C.GoString(C.xdw2txt(C.CString(file))) | |
771 r := strings.NewReader(s) | |
772 tr := transform.NewReader(r, japanese.ShiftJIS.NewDecoder()) | |
773 buf := bufio.NewScanner(tr) | |
774 for buf.Scan() { | |
775 txt = append(txt, buf.Text()) | |
776 } | |
777 return; | |
778 } | |
779 | |
780 func read_conf(file string) (conf Config, err error) { | |
781 content, err := ioutil.ReadFile(file) | |
782 if err != nil { | |
783 log.Fatal(err) | |
784 } | |
785 err = json.Unmarshal(content, &conf) | |
786 return | |
787 } | |
788 | |
789 func print_step(msg string) { | |
790 s := fmt.Sprintf("\n[%d/%d] %s\n", step, totalstep, msg) | |
791 step++ | |
792 fmt.Print(s) | |
793 save_log(s) | |
794 } | |
795 | |
796 func print_time(t time.Time) time.Time { | |
797 now := time.Now() | |
798 if !flg_time { | |
799 return now | |
800 } | |
801 elapsed := now.Sub(t) | |
802 total := now.Sub(start) | |
803 s := fmt.Sprintf("---- Elapsed: %v (total = %v) @ %02d:%02d\n", elapsed, total, now.Hour(), now.Minute()) | |
804 fmt.Print(s) | |
805 save_log(s) | |
806 return now | |
807 } | |
808 | |
809 func print_debug(msg []string) { | |
810 if !flg_debug { | |
811 return | |
812 } | |
813 s := "" | |
814 if len(msg) == 1 { | |
815 s = fmt.Sprintf("----- %s\n", msg) | |
816 } | |
817 for i, s := range msg { | |
818 s += fmt.Sprintf("%05d %s\n", i, s) | |
819 } | |
820 fmt.Print(s) | |
821 save_log(s) | |
822 } | |
823 | |
824 func save_log(logtxt string) error { | |
825 if !flg_log { | |
826 return nil | |
827 } | |
828 f, err := os.OpenFile(logfile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) | |
829 if err != nil { | |
830 return err | |
831 } | |
832 if _, err := f.Write([]byte(logtxt)); err != nil { | |
833 f.Close() | |
834 return err | |
835 } | |
836 if err := f.Close(); err != nil { | |
837 return err | |
838 } | |
839 return nil | |
840 } | |
841 |