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