Mercurial > mercurial > hgweb_kaigo.hg.cgi
comparison Perori/bk.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 bk.go: Insert Biko & Hatsuban | |
3 | |
4 Last Change: 2020-06-24 水 10:16:00. | |
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 char* xdw2txt(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 NULL; | |
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 // メイン処理 | |
39 char *lpszvalue, *all_lpszvalue; | |
40 long datasize[9999]; | |
41 for (int i = 1; i <= nPage; i++) { | |
42 datasize[i] = XDW_GetPageTextToMemory(h, i, NULL, 0, NULL); | |
43 datasize[0] += datasize[i]; | |
44 } | |
45 datasize[0] += nPage - 1; // for "\n" | |
46 all_lpszvalue = (char*)malloc(sizeof(char)*datasize[0]); | |
47 all_lpszvalue[0] = '\0'; | |
48 for (int i = 1; i <= nPage; i++) { | |
49 if (i < nPage) datasize[i]++; // for "\n" | |
50 lpszvalue = (char*)malloc(sizeof(char)*(datasize[i])); | |
51 XDW_GetPageTextToMemory(h, i, lpszvalue, datasize[i], NULL); | |
52 strcat(all_lpszvalue, lpszvalue); | |
53 if (i < nPage) strcat(all_lpszvalue, "\n"); | |
54 free(lpszvalue); | |
55 } | |
56 | |
57 XDW_CloseDocumentHandle(h, NULL); // 文書ハンドルを閉じる | |
58 return all_lpszvalue; | |
59 } | |
60 | |
61 int xdwhb(const char* in_file, const char* out_file, char* hb, const char* stxt) { | |
62 int x = 18000; | |
63 int y = 1200; | |
64 int sz = 110; | |
65 | |
66 char in_path[_MAX_PATH], out_path[_MAX_PATH]; | |
67 _fullpath(in_path, in_file, _MAX_PATH); | |
68 _fullpath(out_path, out_file, _MAX_PATH); | |
69 | |
70 XDW_DOCUMENT_HANDLE h = NULL; | |
71 XDW_OPEN_MODE_EX mode = {sizeof(XDW_OPEN_MODE_EX), XDW_OPEN_UPDATE, XDW_AUTH_NODIALOGUE}; | |
72 | |
73 int api_result = XDW_OpenDocumentHandle(in_path, &h, (XDW_OPEN_MODE*)&mode); | |
74 if (api_result < 0) return api_result; | |
75 | |
76 XDW_DOCUMENT_INFO info = {sizeof(XDW_DOCUMENT_INFO), 0, 0, 0}; | |
77 XDW_GetDocumentInformation(h, &info); | |
78 | |
79 int color = XDW_COLOR_NONE; | |
80 XDW_FOUND_HANDLE pFoundHandle = NULL; | |
81 for (int i = 0; i < info.nPages; i++) { | |
82 api_result = XDW_FindTextInPage(h, i + 1, stxt, NULL, &pFoundHandle, NULL); | |
83 if (pFoundHandle == NULL) continue; | |
84 | |
85 XDW_ANNOTATION_HANDLE annoation; | |
86 int api_result = XDW_AddAnnotation(h, XDW_AID_TEXT, i + 1, x, y, NULL, &annoation, NULL); | |
87 if (api_result < 0) return api_result; | |
88 | |
89 api_result = XDW_SetAnnotationAttribute(h, annoation, XDW_ATN_Text, XDW_ATYPE_STRING, hb, 0, NULL); | |
90 api_result = XDW_SetAnnotationAttribute(h, annoation, XDW_ATN_FontSize, XDW_ATYPE_INT, (char*)&sz, 0, NULL); | |
91 api_result = XDW_SetAnnotationAttribute(h, annoation, XDW_ATN_BackColor, XDW_ATYPE_INT, (char*)&color, 0, NULL); | |
92 } | |
93 | |
94 XDW_SaveDocument(h, NULL); | |
95 XDW_CloseDocumentHandle(h, NULL); | |
96 | |
97 api_result = XDW_OptimizeDocument(in_path, out_path, NULL); | |
98 return 0; | |
99 } | |
100 | |
101 int xdwbiko(const char* in_file, const int page, const int r, char* biko, char* kubun) { | |
102 int x1 = 2000; | |
103 int y1 = 4680 + r * 2720; | |
104 int sz = 90; | |
105 int x2 = 18950; | |
106 int y2 = 5090 + r * 2720; | |
107 | |
108 char in_path[_MAX_PATH]; | |
109 _fullpath(in_path, in_file, _MAX_PATH); | |
110 | |
111 XDW_DOCUMENT_HANDLE h = NULL; | |
112 XDW_OPEN_MODE_EX mode = {sizeof(XDW_OPEN_MODE_EX), XDW_OPEN_UPDATE, XDW_AUTH_NODIALOGUE}; | |
113 | |
114 int api_result = XDW_OpenDocumentHandle(in_path, &h, (XDW_OPEN_MODE*)&mode); | |
115 if (api_result < 0) return api_result; | |
116 | |
117 XDW_DOCUMENT_INFO info = {sizeof(XDW_DOCUMENT_INFO), 0, 0, 0}; | |
118 XDW_GetDocumentInformation(h, &info); | |
119 | |
120 XDW_ANNOTATION_HANDLE annoation1, annoation2; | |
121 int color = XDW_COLOR_NONE; | |
122 | |
123 api_result = XDW_AddAnnotation(h, XDW_AID_TEXT, page, x1, y1, NULL, &annoation1, NULL); | |
124 if (api_result < 0) return api_result; | |
125 api_result = XDW_AddAnnotation(h, XDW_AID_TEXT, page, x2, y2, NULL, &annoation2, NULL); | |
126 if (api_result < 0) return api_result; | |
127 | |
128 api_result = XDW_SetAnnotationAttribute(h, annoation1, XDW_ATN_Text, XDW_ATYPE_STRING, biko, 0, NULL); | |
129 api_result = XDW_SetAnnotationAttribute(h, annoation1, XDW_ATN_FontSize, XDW_ATYPE_INT, (char*)&sz, 0, NULL); | |
130 api_result = XDW_SetAnnotationAttribute(h, annoation1, XDW_ATN_BackColor, XDW_ATYPE_INT, (char*)&color, 0, NULL); | |
131 | |
132 api_result = XDW_SetAnnotationAttribute(h, annoation2, XDW_ATN_Text, XDW_ATYPE_STRING, kubun, 0, NULL); | |
133 api_result = XDW_SetAnnotationAttribute(h, annoation2, XDW_ATN_FontSize, XDW_ATYPE_INT, (char*)&sz, 0, NULL); | |
134 api_result = XDW_SetAnnotationAttribute(h, annoation2, XDW_ATN_BackColor, XDW_ATYPE_INT, (char*)&color, 0, NULL); | |
135 | |
136 XDW_SaveDocument(h, NULL); | |
137 XDW_CloseDocumentHandle(h, NULL); | |
138 | |
139 return 0; | |
140 } | |
141 | |
142 int xdweraren(const char* in_file, const char* stxt) | |
143 { | |
144 int x = 1870; | |
145 int y = 4680; | |
146 int yoff = 2830; | |
147 int sz = 90; | |
148 | |
149 char in_path[_MAX_PATH]; | |
150 _fullpath(in_path, in_file, _MAX_PATH); | |
151 | |
152 XDW_DOCUMENT_HANDLE h = NULL; | |
153 XDW_OPEN_MODE_EX mode = {sizeof(XDW_OPEN_MODE_EX), XDW_OPEN_UPDATE, XDW_AUTH_NODIALOGUE}; | |
154 | |
155 int api_result = XDW_OpenDocumentHandle(in_path, &h, (XDW_OPEN_MODE*)&mode); | |
156 if (api_result < 0) return api_result; | |
157 | |
158 XDW_DOCUMENT_INFO info = {sizeof(XDW_DOCUMENT_INFO), 0, 0, 0}; | |
159 XDW_GetDocumentInformation(h, &info); | |
160 | |
161 XDW_FOUND_HANDLE pFoundHandle = NULL; | |
162 for (int i = 0; i < info.nPages; i++) { | |
163 api_result = XDW_FindTextInPage(h, i + 1, stxt, NULL, &pFoundHandle, NULL); | |
164 if (pFoundHandle != NULL) continue; | |
165 | |
166 for (int r = 0; r < 9; r++) { | |
167 XDW_ANNOTATION_HANDLE annoation; | |
168 int api_result = XDW_AddAnnotation(h, XDW_AID_TEXT, i + 1, x, y + r * yoff, NULL, &annoation, NULL); | |
169 if (api_result < 0) return api_result; | |
170 | |
171 api_result = XDW_SetAnnotationAttribute(h, annoation, XDW_ATN_Text, XDW_ATYPE_STRING, " ", 0, NULL); | |
172 api_result = XDW_SetAnnotationAttribute(h, annoation, XDW_ATN_FontSize, XDW_ATYPE_INT, (char*)&sz, 0, NULL); | |
173 } | |
174 } | |
175 | |
176 XDW_SaveDocument(h, NULL); | |
177 XDW_CloseDocumentHandle(h, NULL); | |
178 | |
179 return 0; | |
180 } | |
181 | |
182 */ | |
183 import "C" | |
184 | |
185 import ( | |
186 "bufio" | |
187 "encoding/csv" | |
188 "fmt" | |
189 "flag" | |
190 "io/ioutil" | |
191 "log" | |
192 "os" | |
193 "regexp" | |
194 "strconv" | |
195 "strings" | |
196 "time" | |
197 | |
198 "golang.org/x/text/encoding/japanese" | |
199 "golang.org/x/text/transform" | |
200 ) | |
201 | |
202 // Constants | |
203 const ( | |
204 version = "0.5" | |
205 default_ccsvfile = "chosairai.csv" | |
206 default_icsvfile = "ikenshoirai.csv" | |
207 default_cxdwfile = "KBPC116G.xdw" | |
208 default_ixdwfile = "KBPB116G.xdw" | |
209 default_tmpxdw = "tmp.xdw" | |
210 default_cout = "outc.xdw" | |
211 default_iout = "outi.xdw" | |
212 default_lout = "xyz.csv" | |
213 ) | |
214 | |
215 var ( | |
216 hbi, hbc string // 発番 | |
217 start time.Time | |
218 | |
219 flg_hb int | |
220 flg_time bool | |
221 | |
222 re_hhsno, re_date, re_city, re_name, re_zensp *regexp.Regexp | |
223 ) | |
224 | |
225 func init(){ | |
226 os.Remove(default_cout) | |
227 os.Remove(default_iout) | |
228 os.Remove(default_lout) | |
229 | |
230 re_hhsno = regexp.MustCompile(`0[1238]00\d{6}`) | |
231 re_date = regexp.MustCompile(`((明治)|(大正)|(昭和)|(平成)|(令和)).{1,2}年.\d月.\d日`) | |
232 re_city = regexp.MustCompile(`(((平成)|(令和)).{1,2}年.\d月.\d日){2}...`) | |
233 re_name = regexp.MustCompile(`0[1238]00\d{6}.*((平成)|(令和)).{1,2}年.\d月.\d日`) | |
234 re_zensp = regexp.MustCompile(` {2,}`) | |
235 } | |
236 | |
237 func main() { | |
238 start = time.Now() | |
239 /* PRINT HEADER */ | |
240 fmt.Println("=======================================") | |
241 fmt.Println(" 備考を...する") | |
242 fmt.Printf(" - bk [ver %s] -\n", version) | |
243 fmt.Println("=======================================\n") | |
244 | |
245 | |
246 /* INITIALIZE FLAGS */ | |
247 today := time.Now().Format("20060102") | |
248 | |
249 flag.StringVar(&today, "d", today, "irai ymd (default today)") | |
250 flag.IntVar(&flg_hb, "b", 0, "set hatsuban (default 0)") | |
251 flag.BoolVar(&flg_time, "t", false, "print time") | |
252 | |
253 flag.Parse() | |
254 | |
255 /* USER INPUT */ | |
256 hbi = fmt.Sprintf("%d", flg_hb) | |
257 if flg_hb == 0 { | |
258 fmt.Print("発番 > ") | |
259 fmt.Scan(&hbi) | |
260 } | |
261 i, err := strconv.Atoi(hbi) | |
262 if err != nil { | |
263 log.Fatal(err) | |
264 } | |
265 hbc = fmt.Sprintf("%d", i + 1) | |
266 | |
267 /* READ BIKO FROM CSV */ | |
268 bhash, err := getBiko_fromCSV(default_ccsvfile, today) | |
269 if err != nil { | |
270 log.Fatal(err) | |
271 } | |
272 fmt.Println(" 備考データ読込 ... done") | |
273 step_start := print_time(start) | |
274 | |
275 /* READ KUBUN FROM CSV */ | |
276 khash, err := getKubun_fromCSV(default_icsvfile, bhash) | |
277 if err != nil { | |
278 log.Fatal(err) | |
279 } | |
280 fmt.Println(" 申請区分データ読込 ... done") | |
281 step_start = print_time(start) | |
282 | |
283 /* INSERT BIKO */ | |
284 var ctxt []string | |
285 copy_tmp(default_cxdwfile) | |
286 for p, t := range xdw2txt(default_cxdwfile) { | |
287 for r, hno := range re_hhsno.FindAllString(t, -1) { | |
288 if bk, ok := bhash[hno]; ok { | |
289 C.xdwbiko(C.CString(default_tmpxdw), C.int(p + 1), C.int(r), C.CString(bk), C.CString(khash[hno])) | |
290 } | |
291 } | |
292 ctxt = append(ctxt, t) | |
293 } | |
294 fmt.Println(" 備考と申請区分を追加 ... done") | |
295 step_start = print_time(step_start) | |
296 | |
297 /* INSERT HATSU-BAN & OPTIMIZE */ | |
298 stxt, _, _ := transform.String(japanese.ShiftJIS.NewEncoder(), "大仙広介") | |
299 C.xdwhb(C.CString(default_tmpxdw), C.CString(default_cout), C.CString(hbc), C.CString(stxt)) | |
300 fmt.Println(" 発番追加(調査依頼ファイル)... done") | |
301 step_start = print_time(step_start) | |
302 | |
303 /* ERASE RENRAKUSAKI */ | |
304 copy_tmp(default_ixdwfile) | |
305 C.xdweraren(C.CString(default_tmpxdw), C.CString(stxt)) | |
306 fmt.Println(" 連絡先消去 ... done") | |
307 step_start = print_time(step_start) | |
308 | |
309 /* INSERT HATSU-BAN & OPTIMIZE */ | |
310 C.xdwhb(C.CString(default_tmpxdw), C.CString(default_iout), C.CString(hbi), C.CString(stxt)) | |
311 fmt.Println(" 発番追加( 意見書依頼ファイル)... done") | |
312 step_start = print_time(step_start) | |
313 | |
314 /* CHOSA IRAI LIST */ | |
315 f, err := os.Create(default_lout) | |
316 if err != nil { | |
317 log.Fatal(err) | |
318 } | |
319 defer f.Close() | |
320 w := bufio.NewWriter(transform.NewWriter(f, japanese.ShiftJIS.NewEncoder())) | |
321 | |
322 header := []string{"申請日", "被保番", "氏名", "生年月日", "市町村", "-", "-", "-", "依頼日"} | |
323 fmt.Fprintln(w, strings.Join(header, ",")) | |
324 | |
325 var req string | |
326 for _, txt := range ctxt { | |
327 str := strings.TrimRight(txt, " ") | |
328 if strings.HasSuffix(str, "依頼書") { | |
329 req = re_date.FindString(str) | |
330 req = strings.Replace(req, " ", "", -1) | |
331 } else { | |
332 row := strings.Split(str, "〒") | |
333 for i := 0; i < len(row) - 1; i++ { | |
334 var app, hhsno, name, birth, city, empty string | |
335 | |
336 d := re_date.FindAllString(row[i], -1) | |
337 if len(d) > 0 { | |
338 birth = strings.Replace(d[0], " ", "", -1) | |
339 app = strings.Replace(d[1], " ", "", -1) | |
340 } | |
341 if re_hhsno.MatchString(row[i]) { | |
342 hhsno = "=\"" + re_hhsno.FindString(row[i]) + "\"" | |
343 } | |
344 if re_name.MatchString(row[i]) { | |
345 n := []rune(re_name.FindString(row[i])) | |
346 kana := string(n[10:36]) | |
347 kana = strings.Trim(kana, " ") | |
348 name = string(n[37:55]) | |
349 name = strings.Trim(name, " ") | |
350 name = re_zensp.ReplaceAllString(name, "") | |
351 name += "(" + kana + ")" | |
352 } | |
353 if re_city.MatchString(row[i]) { | |
354 c := []rune(re_city.FindString(row[i])) | |
355 city = string(c[len(c)-3:]) | |
356 city = strings.Replace(city, "仙北郡", "美郷町", -1) | |
357 } | |
358 | |
359 if hhsno != "" { | |
360 fields := []string{app, hhsno, name, birth, city, empty, empty, empty, req} | |
361 fmt.Fprintln(w, strings.Join(fields, ",")) | |
362 } | |
363 } | |
364 } | |
365 } | |
366 w.Flush() | |
367 | |
368 fmt.Println(" 調査依頼リスト作成 ... done") | |
369 step_start = print_time(step_start) | |
370 | |
371 /* CLEAN */ | |
372 os.Remove(default_tmpxdw) | |
373 fmt.Println(" 終了 ... end") | |
374 step_start = print_time(step_start) | |
375 } | |
376 | |
377 func getBiko_fromCSV(file, date string) (bikohash map[string]string, err error) { | |
378 bikohash = make(map[string]string) | |
379 | |
380 data, err := ioutil.ReadFile(file) | |
381 if err != nil { | |
382 return bikohash, err | |
383 } | |
384 | |
385 r := csv.NewReader(strings.NewReader(string(data))) | |
386 records, err := r.ReadAll() | |
387 if err != nil { | |
388 return bikohash, err | |
389 } | |
390 | |
391 for _, record := range records { | |
392 hno := strings.TrimSpace(record[0]) | |
393 iraiymd := strings.TrimSpace(record[5]) | |
394 if iraiymd != date { | |
395 continue | |
396 } | |
397 bikohash[hno] = record[3] | |
398 } | |
399 | |
400 return bikohash, nil | |
401 } | |
402 | |
403 func getKubun_fromCSV(file string, hhshash map[string]string) (kubunhash map[string]string, err error) { | |
404 kubunhash = make(map[string]string) | |
405 ymdhash := make(map[string]string) | |
406 | |
407 data, err := ioutil.ReadFile(file) | |
408 if err != nil { | |
409 return kubunhash, err | |
410 } | |
411 | |
412 r := csv.NewReader(strings.NewReader(string(data))) | |
413 records, err := r.ReadAll() | |
414 if err != nil { | |
415 return kubunhash, err | |
416 } | |
417 | |
418 for _, record := range records { | |
419 hno := strings.TrimSpace(record[0]) | |
420 if _, ok := hhshash[hno]; !ok { | |
421 continue | |
422 } | |
423 if ymd, ok := ymdhash[hno]; !ok || ymd < record[8] { | |
424 ymdhash[hno] = record[8] | |
425 } | |
426 var buf string | |
427 switch strings.TrimSpace(record[9]) { | |
428 case "01": | |
429 buf = "[新規]" | |
430 case "02": | |
431 buf = "[更新]" | |
432 case "10": | |
433 buf = "[支介]" | |
434 case "05": | |
435 buf = "[区変]" | |
436 case "03": | |
437 buf = "[転入]" | |
438 case "09": | |
439 buf = "[証交]" | |
440 } | |
441 kubun, _, _ := transform.String(japanese.ShiftJIS.NewEncoder(), buf) | |
442 kubunhash[hno] = kubun | |
443 } | |
444 | |
445 return kubunhash, nil | |
446 } | |
447 | |
448 | |
449 func copy_tmp(file string) error { | |
450 os.Remove(default_tmpxdw) | |
451 b, err := ioutil.ReadFile(file) | |
452 if err != nil { | |
453 return err | |
454 } | |
455 if err := ioutil.WriteFile(default_tmpxdw, b, 0644); err != nil { | |
456 return err | |
457 } | |
458 return nil | |
459 } | |
460 | |
461 func xdw2txt(file string) (txt []string) { | |
462 s := C.GoString(C.xdw2txt(C.CString(file))) | |
463 r := strings.NewReader(s) | |
464 tr := transform.NewReader(r, japanese.ShiftJIS.NewDecoder()) | |
465 buf := bufio.NewScanner(tr) | |
466 for buf.Scan() { | |
467 txt = append(txt, buf.Text()) | |
468 } | |
469 return | |
470 } | |
471 | |
472 func print_time(t time.Time) time.Time { | |
473 now := time.Now() | |
474 if !flg_time { | |
475 return now | |
476 } | |
477 elapsed := now.Sub(t) | |
478 total := now.Sub(start) | |
479 s := fmt.Sprintf("---- Elapsed: %v (total = %v) @ %02d:%02d\n", elapsed, total, now.Hour(), now.Minute()) | |
480 fmt.Print(s) | |
481 return now | |
482 } | |
483 |