ken_nogi/NodeJS/Care7_old/pdf解析.js
Kenichiro NOGI 51a95c5e21 NodeJS
2025-07-10 10:12:37 +09:00

290 lines
8.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import fs from 'fs';
//import util from 'util';
import path from 'path';
//コマンド実行モジュール
import childProcess from 'child_process';
//const exec = util.promisify(childProcess.exec);
//--------------------------------------------------------------------------------------------
//フォルダ名定義
const inputDir = 'pdf';
const outputDir = 'output';
const outputCsvDir = 'outputCsv';
//プリザンター実行変数
const pleasanter = 'https://nextoffice.next-hd.co.jp/pleasanter';
//const pleasanter = 'https://neo999.next-hd.net/pleasanter';
const apiKey = '6504c8a807677a3a576e10327f3c19876c55736ee45d4a845796b9e7f5e087bfd4bd0d8184863da8cf1733ca635111432ab334aea59102b06a96ee6d2c05190d';
const uploadSiteId = "126841";
//pdftotext 外部ツール
const appPath = '"./poppler/Library/bin/pdftotext.exe"';
//オプション
const arg = '-layout -nopgbrk';
function main() {
console.log('■■■■■■■■■■■■■■■■■■■■■■■■■■');
//PDFファイル一覧を取得し、外部ツールでテキスト化する
getPDFlist();
console.log('▶▶▶ PDFtoTEXT Complete');
console.log('■■■■■■■■■■■■■■■■■■■■■■■■■■');
//テキスト化したファイルをCSVに変換する
getTEXTlist();
//outputDataAnalyse(pdfPath, output);
}
//--------------------------------------------------------------------------------------------
//PDFファイル一覧を取得し、外部ツールでテキスト化する
function getPDFlist() {
//pdfファイル一覧
let files = fs.readdirSync(inputDir, {
withFileTypes: true
}).filter(dirent => dirent.isFile()).map(({
name
}) => name) //フォルダ除外
.filter(function (file) {
return path.extname(file).toLowerCase() === '.pdf'; //拡張子pdfだけ
});
console.log(files);
files.forEach(function (file) {
let fileName = path.parse(file).name; //ファイル名取得
//ファイル名が6文字(YYYYMM)の場合のみ実行する
if (fileName.length == 6) {
let year = parseFloat(fileName.substring(0, 4));
let month = parseFloat(fileName.substring(4, 6));
//年と月の範囲を確認し、範囲内なら実行する
if (year > 2000 && year < 2100 && month >= 1 && month <= 12) {
let inputPath = './' + inputDir + '/' + file;
let outputPath = './' + outputDir + '/' + file.replace('pdf', 'txt');
console.log('>>> 1.TEXT抽出 処理開始------------');
//PdftoTextコマンドと連結
let cmd = appPath + ' ' + arg + ' ' + inputPath + ' ' + outputPath;
console.log(cmd);
//外部コマンドを実行する
childProcess.execSync(cmd);
console.log('-------------------------------1-DONE');
//完了後、ファイルを移動
console.log('>>> 2.Move PDF file : ' + inputPath);
let completePath = './' + inputDir + '/complete/' + file;
fs.renameSync(inputPath, completePath);
console.log('-------------------------------2-DONE');
}
}
});
}
function getTEXTlist() {
//txtファイル一覧
let files = fs.readdirSync(outputDir, {
withFileTypes: true
}).filter(dirent => dirent.isFile()).map(({
name
}) => name) //フォルダ除外
.filter(function (file) {
return path.extname(file).toLowerCase() === '.txt'; //拡張子txtだけ
});
console.log(files);
//ファイル名から年と月を取得
//
files.forEach(function (file) {
console.log('>>> 3.CSV変換 処理開始------------')
//ファイル情報取得
let fileName = path.parse(file).name; //ファイル名取得
let year = fileName.substring(0, 4);
let month = fileName.substring(4, 6);
let inputPath = './' + outputDir + '/' + file;
let outputPath = './' + outputCsvDir + '/' + file.replace('txt', 'csv');
outputDataAnalyse(inputPath, outputPath, year, month);
console.log('-------------------------------3-DONE');
console.log('>>> 4.CSVアップロード 処理開始------------')
importToPleasanter(outputPath, "UTF-8", true, uploadSiteId, "Title");
});
}
function outputDataAnalyse(inputPath, outputPath, year, month) {
let csvData = fs.readFileSync(inputPath);
let lines = csvData.toString().split('\n');
fs.writeFileSync(outputPath, '識別コード,主/副,担当者名,訪問時間,終了時間,対応時間,予防,内容,その他,クライアント,主/副担当者\n');
let sub = "";
lines.forEach(function (line) {
//console.log(line);
line = line.replace(//gm, ' '); //コロン スペース変換
line = line.replace(//gm, ' '); //コロン スペース変換
line = line.replace("副)", ' 副 '); //コロン スペース変換
line = line.replace(/\(/gm, ''); //カッコ削除
line = line.replace("分)", ''); //カッコ削除
line = line.replace(/^\s+/gm, ''); //行頭スペース削除
line = line.replace(/\s$/gm, ''); //行末スペース削除
line = line.replace(/\s+/gm, ' '); //多重スペース縮小
let data = line.split(/\s/); //スペースで区切り
if (data.length == 1) sub = data[0];
if (data.length > 10 && data.length < 18) {
if (data[1] != '副') {
data.splice(1, 0, '主');
}
if (data[10] == '予防') {
data.splice(12, 0, sub);
sub = "";
} else {
data.splice(10, 0, "");
data.splice(12, 0, sub);
sub = "";
}
if (data.length == 15) {
data.splice(16, 0, '');
data.splice(17, 0, '');
}
let output = data.join(','); //カンマ保存
//if (data.length == 16) console.log(data.length + ' ' + data);
//インポート用CSVデータ作成
let recordData = year + '.' + month + '_' + data[2] + data[3] + '_' + data[0] + ',' +
data[1] + ',' +
data[2] + ' ' + data[3] + ',' +
year + '/' + month + '/' + data[4] + ' ' + data[5] + ':' + data[6] + ':00' + ',' +
year + '/' + month + '/' + data[4] + ' ' + data[7] + ':' + data[8] + ':00' + ',' +
data[9] + ',' +
data[10] + ',' +
data[11] + ',' +
data[12] + ',' +
data[13] + ' ' + data[14] + ',';
if (data[15] != '') {
recordData += data[15] + ' ' + data[16];
}
//console.log(recordData);
fs.appendFileSync(outputPath, recordData + '\n');
}
});
}
function importToPleasanter(importFile, encoding, updatableImport, siteId, key) {
const url = pleasanter + '/api/items/' + siteId + '/import';
const csvData = fs.readFileSync(importFile, 'utf-8');
//送信データ
let formData = new FormData();
let json = {
"ApiVersion": 1.1,
"ApiKey": apiKey,
"Encoding": encoding,
"UpdatableImport": updatableImport,
"Key": key
};
formData.append('parameters', JSON.stringify(json));
formData.append('file', new Blob([csvData]));
fetch(url, {
"method": 'POST',
"body": formData
}).then((response) => {
if (!response.ok) {
throw new Error(`${response.status} ${response.statusText}`);
console.log(response);
}
// レスポンスが JSON 形式で返っていることを想定
return response.json();
}).then((data) => {
console.log('** fetch: then(data)');
console.log(data);
console.log('-------------------------------4-DONE');
}).catch((reason) => {
// エラー処理
console.log('** fetch: catch');
console.log(reason);
});
}
/*
function importToPleasanter(importFile, encoding, updatableImport, siteId, key) {
const url = pleasanter + '/api/items/' + siteId + '/import';
const csvData = fs.readFileSync(importFile);
//送信データ
let json = {
"ApiVersion": 1.1,
"ApiKey": apiKey,
"Encoding": encoding,
"UpdatableImport": updatableImport,
"Key": key
};
//データ取得リクエスト
const xhr = new XMLHttpRequest(); //XMLHttpRequestの作成
//HTTPリクエスト実行
xhr.open('POST', url, true);
xhr.setRequestHeader('Content-Type', 'application/json;charset=utf-8');
xhr.onload = () => { //XMLHttpRequestのリクエストステータスの確認
if (xhr.status === 200) {
//success
let data = JSON.parse(xhr.responseText);
//結果を配列に結合
resData = resData.concat(data.Response.Data);
//全件取得するまで繰り返す
if ((data.Response.Offset + data.Response.PageSize) <= data.Response.TotalCount) {
sendRequest(data.Response.Offset + data.Response.PageSize);
} else {
//全件取得したら配列の各要素を処理
resData.forEach(function (value) {
const result = dataCreate(value);
if (!result) {
console.log(value);
console.log("Update Failed!!");
return;
}
});
}
} else {
//error
console.log(JSON.parse(xhr.responseText));
}
};
xhr.send(JSON.stringify(json));
}
*/
//始動
main();