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 |
