发票数据自动填充(支持TXT导入/粘贴+持久化)
// ==UserScript==
// @name 发票数据自动填充(支持TXT导入/粘贴+持久化)
// @namespace http://tampermonkey.net/
// @version 1.2
// @description 从TXT文件或粘贴文本导入数据,自动保存进度
// @match https://inv-veri.chinatax.gov.cn/*
// @grant GM_setValue
// @grant GM_getValue
// ==/UserScript==
(function() {
// 全局变量
let invoicesArray = [];
let currentIndex = 0;
let statusSpan;
let nextBtn, prevBtn;
// 初始化UI界面
function initUI() {
const uiDiv = document.createElement('div');
uiDiv.style.cssText = `
position: fixed;
bottom: 10px;
right: 10px;
background: #fff;
padding: 8px;
border: 1px solid #ccc;
z-index: 9999;
font-family: Arial, sans-serif;
width: 260px;
font-size: 12px;
`;
// 创建按钮样式
const buttonStyle = `
padding: 3px 8px;
margin: 2px;
font-size: 12px;
line-height: 1.2;
`;
// 文件上传区域
const fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.accept = '.txt';
fileInput.style.marginBottom = '10px';
// 文本粘贴区域
const pasteArea = document.createElement('textarea');
pasteArea.placeholder = '或直接粘贴发票数据(每行一个)...';
pasteArea.style.width = '100%';
pasteArea.style.height = '40px';
pasteArea.style.marginBottom = '10px';
// 操作按钮
const loadBtn = document.createElement('button');
loadBtn.textContent = '加载数据';
loadBtn.style.cssText = buttonStyle;
const clearBtn = document.createElement('button');
clearBtn.textContent = '清空数据';
clearBtn.style.cssText = buttonStyle;
// 翻页控制区域
const navDiv = document.createElement('div');
navDiv.style.marginTop = '10px';
prevBtn = document.createElement('button');
prevBtn.textContent = '上一条 (P)';
prevBtn.style.cssText = buttonStyle;
nextBtn = document.createElement('button');
nextBtn.textContent = '下一条 (Z)';
nextBtn.style.cssText = buttonStyle;
statusSpan = document.createElement('span');
statusSpan.style.margin = '0 10px';
// 组装UI组件
uiDiv.appendChild(fileInput);
uiDiv.appendChild(pasteArea);
uiDiv.appendChild(document.createElement('br'));
uiDiv.appendChild(loadBtn);
uiDiv.appendChild(clearBtn);
navDiv.appendChild(prevBtn);
navDiv.appendChild(statusSpan);
navDiv.appendChild(nextBtn);
uiDiv.appendChild(navDiv);
document.body.appendChild(uiDiv);
return { fileInput, pasteArea, loadBtn, clearBtn };
}
// 保存数据到本地存储
function saveData() {
localStorage.setItem('invoiceData', JSON.stringify({
data: invoicesArray,
index: currentIndex
}));
}
// 填充输入框
function fillInput(index) {
const input = document.querySelector('#fpdm');
if (!input) return alert('错误:未找到发票代码输入框!');
input.value = invoicesArray[index];
input.dispatchEvent(new Event('input', { bubbles: true }));
updateStatus();
saveData();
}
// 更新状态显示
function updateStatus() {
statusSpan.textContent = `${currentIndex + 1}/${invoicesArray.length}`;
}
// 加载上一条数据
function loadPrevious() {
if (currentIndex > 0) {
currentIndex--;
fillInput(currentIndex);
} else {
alert('已经是第一条数据!');
}
}
// 加载下一条数据
function loadNext() {
if (currentIndex < invoicesArray.length - 1) {
currentIndex++;
fillInput(currentIndex);
} else {
alert('已经是最后一条数据!');
}
}
// 加载数据(从文件或粘贴文本)
function loadData(source, content) {
if (!content) return alert('错误:数据为空!');
invoicesArray = content.split('\n')
.map(line => line.trim())
.filter(line => line.length > 0);
if (invoicesArray.length === 0) {
return alert('错误:未找到有效数据!');
}
currentIndex = 0;
fillInput(currentIndex);
}
// 主函数
function main() {
const { fileInput, pasteArea, loadBtn, clearBtn } = initUI();
// 设置快捷键监听
document.addEventListener('keydown', (e) => {
if (!e.ctrlKey && !e.shiftKey && e.altKey) {
if (e.key.toLowerCase() === 'p') loadPrevious();
if (e.key.toLowerCase() === 'z') loadNext();
}
});
// 绑定按钮事件
prevBtn.addEventListener('click', loadPrevious);
nextBtn.addEventListener('click', loadNext);
loadBtn.addEventListener('click', () => {
if (pasteArea.value.trim()) {
loadData('paste', pasteArea.value.trim());
} else if (fileInput.files[0]) {
fileInput.files[0].text().then(content => {
loadData('file', content);
});
} else {
alert('请先上传文件或粘贴文本!');
}
});
clearBtn.addEventListener('click', () => {
invoicesArray = [];
currentIndex = 0;
localStorage.removeItem('invoiceData');
statusSpan.textContent = '未加载数据';
pasteArea.value = '';
fileInput.value = '';
});
// 尝试加载本地存储的数据
const savedData = localStorage.getItem('invoiceData');
if (savedData) {
try {
const { data, index } = JSON.parse(savedData);
invoicesArray = data;
currentIndex = index;
updateStatus();
} catch (e) {
console.error('加载本地数据失败:', e);
}
} else {
statusSpan.textContent = '未加载数据';
}
}
// 页面加载完成后执行
if (document.readyState === 'complete') {
main();
} else {
document.addEventListener('DOMContentLoaded', main);
}
})();