Mercurial > mercurial > hgweb_golang.cgi
comparison src/kaigo/Nk/nk.go @ 41:34a474fb83c3
add perori/porori/nk.
author | pyon@macmini |
---|---|
date | Wed, 04 Mar 2020 23:46:59 +0900 |
parents | |
children | c58172a59534 |
comparison
equal
deleted
inserted
replaced
40:c6df3bae683e | 41:34a474fb83c3 |
---|---|
1 /* | |
2 nk.go: Nintei Kekka | |
3 | |
4 Last Change: 2020-01-24 金 09:18:04. | |
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 xdwaddatn(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 xdw2pdf(const char* xdwfile, const char* pdffile) { | |
279 char in_path[_MAX_PATH], out_path[_MAX_PATH]; | |
280 _fullpath(in_path, xdwfile, _MAX_PATH); | |
281 _fullpath(out_path, pdffile, _MAX_PATH); | |
282 | |
283 remove(out_path); | |
284 int api_result = 0; | |
285 | |
286 XDW_DOCUMENT_HANDLE h = NULL; | |
287 XDW_OPEN_MODE_EX mode = {sizeof(XDW_OPEN_MODE_EX), XDW_OPEN_READONLY, XDW_AUTH_NODIALOGUE}; | |
288 | |
289 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_IMAGE_OPTION_PDF pdf = { | |
296 sizeof(XDW_IMAGE_OPTION_PDF), | |
297 XDW_COMPRESS_MRC_NORMAL, | |
298 XDW_CONVERT_MRC_OS, | |
299 info.nPages | |
300 }; | |
301 | |
302 XDW_IMAGE_OPTION_EX ex = { | |
303 sizeof(XDW_IMAGE_OPTION_EX), | |
304 600, // dpi | |
305 XDW_IMAGE_MONO_HIGHQUALITY, | |
306 XDW_IMAGE_PDF, | |
307 &pdf | |
308 }; | |
309 | |
310 api_result = XDW_ConvertPageToImageFile(h, 1, out_path, (XDW_IMAGE_OPTION*)&ex); | |
311 | |
312 XDW_SaveDocument(h, NULL); | |
313 XDW_CloseDocumentHandle(h, NULL); | |
314 | |
315 return 0; | |
316 } | |
317 | |
318 int xdwopt(const char* in, const char* out) { | |
319 char in_path[_MAX_PATH], out_path[_MAX_PATH]; | |
320 _fullpath(in_path, in, _MAX_PATH); | |
321 _fullpath(out_path, out, _MAX_PATH); | |
322 | |
323 int api_result = XDW_OptimizeDocument(in_path, out_path, NULL); | |
324 return (api_result >= 0); | |
325 } | |
326 */ | |
327 import "C" | |
328 | |
329 import ( | |
330 "bufio" | |
331 "encoding/json" | |
332 "fmt" | |
333 "flag" | |
334 "io/ioutil" | |
335 "log" | |
336 "os" | |
337 "os/exec" | |
338 "path/filepath" | |
339 "regexp" | |
340 "sort" | |
341 "strings" | |
342 "time" | |
343 | |
344 "golang.org/x/text/encoding/japanese" | |
345 "golang.org/x/text/transform" | |
346 ) | |
347 | |
348 var ( | |
349 ver = "0.1" | |
350 | |
351 flg_hb int | |
352 flg_time bool | |
353 flg_log bool | |
354 flg_debug bool | |
355 flg_clean bool | |
356 | |
357 confjson = "nk.json" | |
358 logfile = "nk.log" | |
359 hhscsv = "hhsdb.csv" | |
360 tmpdir string | |
361 tmpprefix = "nktemp_" | |
362 inputdir = "input" | |
363 outputdir = "output" | |
364 outcsv = "out.csv" | |
365 | |
366 start time.Time | |
367 | |
368 hb string // 発番 | |
369 fw, hs, kt = "", "", "kttemp.xdw" // 負担割合証, 被保険者証, 結果通知 | |
370 | |
371 step, totalstep = 1, 13 | |
372 ) | |
373 | |
374 type Annotation struct { | |
375 X, Y int | |
376 Sz int | |
377 Tr bool | |
378 Txt string | |
379 } | |
380 | |
381 type Config struct { | |
382 Atns []Annotation | |
383 Kyotaku []string | |
384 } | |
385 | |
386 func (c *Config) ProcessTemplate() { | |
387 today := time.Now().Format("令和 r 年 1 月 2 日") | |
388 y := time.Now().Year() - 2018 | |
389 if y == 1 { | |
390 today = strings.ReplaceAll(today, "r", "元") | |
391 } else { | |
392 today = strings.ReplaceAll(today, "r", fmt.Sprintf("%d", y)) | |
393 } | |
394 | |
395 var atns []Annotation | |
396 for _, atn := range c.Atns { | |
397 s := atn.Txt | |
398 if atn.Txt == "date" { | |
399 s = today | |
400 } | |
401 if strings.ContainsAny(atn.Txt, "hb") { | |
402 s = strings.ReplaceAll(atn.Txt, "hb", hb) | |
403 } | |
404 atns = append(atns, Annotation{atn.X, atn.Y, atn.Sz, atn.Tr, s}) | |
405 } | |
406 c.Atns = atns | |
407 } | |
408 | |
409 func (c *Config) KyotakuList() []string { | |
410 return c.Kyotaku | |
411 } | |
412 | |
413 func (c *Config) AnnotationList() (al []string) { | |
414 for _, atn := range c.Atns { | |
415 tr := 0 | |
416 if atn.Tr { | |
417 tr = 1 | |
418 } | |
419 s := fmt.Sprintf("%d,%d,%d,%d,%s", atn.X, atn.Y, atn.Sz, tr, atn.Txt) | |
420 al = append(al, s) | |
421 } | |
422 return | |
423 } | |
424 | |
425 func init() { | |
426 /* INITIALIZE FLAGS */ | |
427 flag.IntVar(&flg_hb, "b", 0, "set hatsuban") | |
428 flag.BoolVar(&flg_time, "t", false, "print time") | |
429 flag.BoolVar(&flg_log, "l", false, "save log") | |
430 flag.BoolVar(&flg_debug, "d", false, "print data for debug") | |
431 flag.BoolVar(&flg_clean, "c", false, "clean temporary directory & exit") | |
432 | |
433 /* CREAN OUTPUT-FILE & TEMP-FILE */ | |
434 if err := os.RemoveAll(outputdir); err != nil { | |
435 log.Fatal(err) | |
436 } | |
437 os.Remove(logfile) | |
438 | |
439 /* PREPARATE OUTPUT-DIR & TEMP-DIR */ | |
440 if err := os.Mkdir(outputdir, 0755); err != nil { | |
441 log.Fatal(err) | |
442 } | |
443 | |
444 var err error | |
445 tmpdir, err = ioutil.TempDir(".", tmpprefix) | |
446 if err != nil { | |
447 log.Fatal(err) | |
448 } | |
449 logfile = filepath.Join(tmpdir, logfile) | |
450 kt = filepath.Join(tmpdir, kt) | |
451 } | |
452 | |
453 func main() { | |
454 flag.Parse() | |
455 | |
456 /* CLEAN TEMPORARY DIRECTORY */ | |
457 if flg_clean { | |
458 files, err := ioutil.ReadDir(".") | |
459 if err != nil { | |
460 log.Fatal(err) | |
461 } | |
462 for _, file := range files { | |
463 if strings.HasPrefix(file.Name(), tmpprefix) { | |
464 if err := os.RemoveAll(file.Name()); err != nil { | |
465 log.Fatal(err) | |
466 } | |
467 } | |
468 } | |
469 os.Exit(0) | |
470 } | |
471 | |
472 /* PRINT HEADER */ | |
473 fmt.Println("=======================================") | |
474 fmt.Println(" 被保険者証と結果通知と負担割合証を... ") | |
475 fmt.Printf(" - nk [ver %s] -\n", ver) | |
476 fmt.Println("=======================================\n") | |
477 | |
478 /* USER INPUT */ | |
479 hb = fmt.Sprintf("%d", flg_hb) | |
480 if flg_hb == 0 { | |
481 fmt.Print("発番 > ") | |
482 fmt.Scan(&hb) | |
483 } | |
484 | |
485 start = time.Now() | |
486 | |
487 /* READ CONFIG FROM JSON */ | |
488 print_step("設定読込み") | |
489 conf, err := read_conf(confjson) | |
490 if err != nil { | |
491 log.Fatal(err) | |
492 } | |
493 conf.ProcessTemplate() | |
494 step_start := print_time(start) | |
495 | |
496 /* CHECK INPUT-FILE */ | |
497 print_step("入力ファイルのチェック") | |
498 files, err := ioutil.ReadDir(inputdir) | |
499 if err != nil { | |
500 log.Fatal(err) | |
501 } | |
502 | |
503 var kts []string | |
504 for _, file := range files { | |
505 if strings.HasSuffix(file.Name(), ".xdw") { | |
506 print_debug([]string{file.Name()}) | |
507 switch file.Name()[0:8] { | |
508 case "KBPV016G": | |
509 fw = filepath.Join(inputdir, file.Name()) | |
510 case "KBPG316G": | |
511 hs = filepath.Join(inputdir, file.Name()) | |
512 case "KBPG206G", "KBPG706G": | |
513 f := filepath.Join(inputdir, file.Name()) | |
514 kts = append(kts, f) | |
515 } | |
516 } | |
517 } | |
518 | |
519 fmt.Println() | |
520 fmt.Printf(" 負担割合証ファイル = %s\n", fw) | |
521 fmt.Printf(" 被保険者証ファイル = %s\n", hs) | |
522 fmt.Print(" 結果通知ファイル =") | |
523 for _, f := range kts { | |
524 fmt.Printf(" %s", f) | |
525 } | |
526 fmt.Println() | |
527 if fw == "" || hs == "" || len(kts) == 0 { | |
528 fmt.Fprintf(os.Stderr, "Input file is wrong.\n") | |
529 os.Exit(1) | |
530 } | |
531 | |
532 bytes, err := ioutil.ReadFile(hhscsv) | |
533 if err != nil { | |
534 log.Fatal(err) | |
535 } | |
536 hash_hhs := make(map[string]string) // 被保険者氏名のハッシュ | |
537 r := strings.NewReader(string(bytes)) | |
538 tr := transform.NewReader(r, japanese.ShiftJIS.NewDecoder()) | |
539 buf := bufio.NewScanner(tr) | |
540 for buf.Scan() { | |
541 records := strings.Split(buf.Text(), ",") | |
542 hash_hhs[records[0]] = records[2] | |
543 } | |
544 fmt.Printf(" 被保険者ファイル = %s\n", hhscsv) | |
545 | |
546 step_start = print_time(step_start) | |
547 | |
548 /* CONCATNATE INPUT-FILE */ | |
549 print_step("結果通知ファイルの連結") | |
550 b, err := ioutil.ReadFile(kts[0]) | |
551 if err != nil { | |
552 log.Fatal(err) | |
553 } | |
554 if err = ioutil.WriteFile(kt, b, 0644); err != nil { | |
555 log.Fatal(err) | |
556 } | |
557 if len(kts) > 1 { | |
558 pp := 0 | |
559 fmt.Println() | |
560 for _, file := range kts { | |
561 p, _ := C.xdwpages(C.CString(file)) | |
562 fmt.Printf(" %s\t= %d ページ\n", file, int(p)) | |
563 pp += int(p) | |
564 } | |
565 fmt.Printf(" 合計\t= %d ページ\n", pp) | |
566 for _, file := range kts[1:] { | |
567 C.xdwpush(C.CString(kt), C.CString(file)) | |
568 } | |
569 } | |
570 step_start = print_time(step_start) | |
571 | |
572 /* MAKE SORT-TABEL */ | |
573 print_step("並び順の決定") | |
574 | |
575 re_hhs := regexp.MustCompile(`05((2126)|(2159)|(4346))0[1238]\d{8}`) | |
576 re_kaigo := regexp.MustCompile(`要((介護)|(支援)).`) | |
577 | |
578 hash_fw := make(map[string]int) // 負担割合証発行者のハッシュ | |
579 for _, t := range xdw2txt(fw) { | |
580 hash_fw[re_hhs.FindString(t)]++ | |
581 print_debug([]string{re_hhs.FindString(t)}) | |
582 } | |
583 | |
584 kyotaku := conf.KyotakuList() | |
585 | |
586 hash_kaigo := make(map[string]string) // 被保険者証発行者の要介護度のハッシュ | |
587 hash_kyotaku := make(map[string]string) // 被保険者証発行者の居宅介護支援事業所のハッシュ | |
588 var sorttable []string | |
589 for _, t := range xdw2txt(hs) { | |
590 h := re_hhs.FindString(t) | |
591 hash_kaigo[h] = re_kaigo.FindString(t) | |
592 for _, k := range kyotaku { | |
593 if strings.Contains(t, k) { | |
594 hash_kyotaku[h] = k | |
595 } | |
596 } | |
597 key := make_sort_key(hash_fw[h], re_kaigo.FindString(t), h) | |
598 s := fmt.Sprintf("%s#%d:%s:%s#%s", key, hash_fw[h], re_kaigo.FindString(t), hash_kyotaku[h], h) | |
599 sorttable = append(sorttable, s) | |
600 } | |
601 //sort.Sort(sort.Reverse(sort.StringSlice(sorttable))) | |
602 sort.Sort(sort.StringSlice(sorttable)) | |
603 print_debug(sorttable) | |
604 step_start = print_time(step_start) | |
605 | |
606 /* DO SORT */ | |
607 order := "" | |
608 for _, s := range sorttable { | |
609 t := strings.Split(s, "#") | |
610 order += ":" + t[len(t)-1][6:] | |
611 } | |
612 order = strings.Replace(order, ":", "", 1) | |
613 | |
614 print_step("被保険者証並び替え") | |
615 hs_sorted := filepath.Join(tmpdir, "hs.xdw") | |
616 C.xdwsort(C.CString(hs), C.CString(hs_sorted), C.CString(order), C.CString(tmpdir), C.CString("hs")) | |
617 step_start = print_time(step_start) | |
618 | |
619 print_step("負担割合証並び替え") | |
620 fw_sorted := filepath.Join(tmpdir, "fw.xdw") | |
621 C.xdwsort(C.CString(fw), C.CString(fw_sorted), C.CString(order), C.CString(tmpdir), C.CString("fw")) | |
622 step_start = print_time(step_start) | |
623 | |
624 print_step("結果通知並び替え") | |
625 kt_sorted := filepath.Join(tmpdir, "kt.xdw") | |
626 C.xdwsort(C.CString(kt), C.CString(kt_sorted), C.CString(order), C.CString(tmpdir), C.CString("kt")) | |
627 step_start = print_time(step_start) | |
628 | |
629 /* ADD ANNOTATION */ | |
630 print_step("発番印字") | |
631 al := strings.Join(conf.AnnotationList(), ":") | |
632 al, _, _ = transform.String(japanese.ShiftJIS.NewEncoder(), al) | |
633 C.xdwaddatn(C.CString(kt_sorted), C.CString(al)) | |
634 step_start = print_time(step_start) | |
635 | |
636 /* OPTIMIZE OUTPUT-FILE */ | |
637 print_step("最適化") | |
638 hs_opt := filepath.Join(outputdir, "hs.xdw") | |
639 C.xdwopt(C.CString(hs_sorted), C.CString(hs_opt)) | |
640 fw_opt := filepath.Join(outputdir, "fw.xdw") | |
641 C.xdwopt(C.CString(fw_sorted), C.CString(fw_opt)) | |
642 kt_opt := filepath.Join(outputdir, "kt.xdw") | |
643 C.xdwopt(C.CString(kt_sorted), C.CString(kt_opt)) | |
644 step_start = print_time(step_start) | |
645 | |
646 /* OUTPUT CSV */ | |
647 print_step("CSV出力") | |
648 outcsv = filepath.Join(outputdir, outcsv) | |
649 fcsv, err := os.OpenFile(outcsv, os.O_RDWR|os.O_CREATE, 0644) | |
650 if err != nil { | |
651 log.Fatal(err) | |
652 } | |
653 for i, s := range sorttable { | |
654 t := strings.Split(s, "#") | |
655 u := strings.ReplaceAll(t[1], ":", ",") | |
656 u, _, _ = transform.String(japanese.ShiftJIS.NewEncoder(), u) | |
657 c := t[2][0:6] | |
658 h := t[2][6:16] | |
659 n, _, _ := transform.String(japanese.ShiftJIS.NewEncoder(), hash_hhs[h]) | |
660 // seq, city, hno, name, kaigo, fw, kyotaku | |
661 fmt.Fprintf(fcsv, "%04d,%s,%s,%s,%s\n", i + 1, c, h, n, u) | |
662 } | |
663 if err := fcsv.Close(); err != nil { | |
664 log.Fatal(err) | |
665 } | |
666 step_start = print_time(step_start) | |
667 | |
668 /* PDF */ | |
669 print_step("負担割合証割付PDF作成") | |
670 fwpdf := filepath.Join(tmpdir, "fw.pdf") | |
671 C.xdw2pdf(C.CString(fw_opt), C.CString(fwpdf)) // 2min | |
672 step_start = print_time(step_start) | |
673 | |
674 print_step("負担割合証PDF割付") | |
675 fw4pdf := filepath.Join(outputdir, "fw4.pdf") | |
676 cmd := exec.Command("fw4.exe", fwpdf, fw4pdf, tmpdir) | |
677 if err := cmd.Run(); err != nil { | |
678 log.Fatal(err) | |
679 } | |
680 step_start = print_time(step_start) | |
681 | |
682 print_step("終了") | |
683 step_start = print_time(step_start) | |
684 | |
685 /* REMOVE TEMP-FILE */ | |
686 if flg_log { | |
687 logfile2 := filepath.Join(".", strings.Replace(logfile, tmpdir, "", 1)) | |
688 os.Link(logfile, logfile2) | |
689 } | |
690 | |
691 if !flg_debug { | |
692 if err := os.RemoveAll(tmpdir); err != nil { | |
693 log.Fatal(err) | |
694 } | |
695 } | |
696 } | |
697 | |
698 func make_sort_key(fw int, kaigo, h string) string { | |
699 key := fmt.Sprintf("%d:", 9 - fw) | |
700 if strings.HasPrefix(kaigo, "要支援") { | |
701 key += "1" | |
702 } | |
703 if strings.HasPrefix(kaigo, "要介護") { | |
704 key += "2" | |
705 } | |
706 switch { | |
707 case strings.HasSuffix(kaigo, "1"): | |
708 key += "1:" | |
709 case strings.HasSuffix(kaigo, "2"): | |
710 key += "2:" | |
711 case strings.HasSuffix(kaigo, "3"): | |
712 key += "3:" | |
713 case strings.HasSuffix(kaigo, "4"): | |
714 key += "4:" | |
715 case strings.HasSuffix(kaigo, "5"): | |
716 key += "5:" | |
717 default: | |
718 key += "00:" | |
719 } | |
720 return key + h | |
721 } | |
722 | |
723 func xdw2txt(file string) (txt []string) { | |
724 s := C.GoString(C.xdw2txt(C.CString(file))) | |
725 r := strings.NewReader(s) | |
726 tr := transform.NewReader(r, japanese.ShiftJIS.NewDecoder()) | |
727 buf := bufio.NewScanner(tr) | |
728 for buf.Scan() { | |
729 txt = append(txt, buf.Text()) | |
730 } | |
731 return; | |
732 } | |
733 | |
734 func read_conf(file string) (conf Config, err error) { | |
735 content, err := ioutil.ReadFile(file) | |
736 if err != nil { | |
737 log.Fatal(err) | |
738 } | |
739 err = json.Unmarshal(content, &conf) | |
740 return | |
741 } | |
742 | |
743 func print_step(msg string) { | |
744 s := fmt.Sprintf("\n[%d/%d] %s\n", step, totalstep, msg) | |
745 step++ | |
746 fmt.Print(s) | |
747 save_log(s) | |
748 } | |
749 | |
750 func print_time(t time.Time) time.Time { | |
751 now := time.Now() | |
752 if !flg_time { | |
753 return now | |
754 } | |
755 elapsed := now.Sub(t) | |
756 total := now.Sub(start) | |
757 s := fmt.Sprintf("---- Elapsed: %v (total = %v) @ %02d:%02d\n", elapsed, total, now.Hour(), now.Minute()) | |
758 fmt.Print(s) | |
759 save_log(s) | |
760 return now | |
761 } | |
762 | |
763 func print_debug(msg []string) { | |
764 if !flg_debug { | |
765 return | |
766 } | |
767 s := "" | |
768 if len(msg) == 1 { | |
769 s = fmt.Sprintf("----- %s\n", msg) | |
770 } | |
771 for i, s := range msg { | |
772 s += fmt.Sprintf("%05d %s\n", i, s) | |
773 } | |
774 fmt.Print(s) | |
775 save_log(s) | |
776 } | |
777 | |
778 func save_log(logtxt string) error { | |
779 if !flg_log { | |
780 return nil | |
781 } | |
782 f, err := os.OpenFile(logfile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) | |
783 if err != nil { | |
784 return err | |
785 } | |
786 if _, err := f.Write([]byte(logtxt)); err != nil { | |
787 f.Close() | |
788 return err | |
789 } | |
790 if err := f.Close(); err != nil { | |
791 return err | |
792 } | |
793 return nil | |
794 } | |
795 |