一、公文落款的格式
公文落款包括单位署名和成文日期两个部分,其中成文日期中的数字 用阿拉伯数字将年、月、日标全,年份应标全称,月、日不编虚位(即 1 不编为 01)。
在实际应用工作中分为三种情况:
(一)加盖印章的公文
成文日期一般右空四字编排,印章用红色,不得出现空白印章。
单一机关行文时,一般在成文日期之上、以成文日期为准居中编排发文机关署名,印章端正、 居中下压发文机关署名和成文日期,使发文机关署名和成文日期居印章中心偏下位置,印章顶端应 当上距正文(或附件说明)一行之内。 联合行文时,一般将各发文机关署名按照发文机关顺序整齐排列在相应位置,并将印章一一对 应、端正、居中下压发文机关署名,最后一个印章端正、居中下压发文机关署名和成文日期,印章 之间排列整齐、互不相交或相切,每排印章两端不得超出版心,首排印章顶端应当上距正文(或附 件说明)一行之内。
(二)不加盖印章的公文
单一机关行文时,在正文(或附件说明)下空一行右空二字编排发文机关署名,在发文机关署名下一行编排成文日期,首字比发文机关署名首字右移二字,如成文日期长于发文机关署名,应当 使成文日期右空二字编排,并相应增加发文机关署名右空字数。 联合行文时,应当先编排主办机关署名,其余发文机关署名依次向下编排。
(三)加盖签发人签名章的公文
单一机关制发的公文加盖签发人签名章时,在正文(或附件说明)下空二行右空四字加盖签发 人签名章,签名章左空二字标注签发人职务,以签名章为准上下居中排布。在签发人签名章下空一 行右空四字编排成文日期。 联合行文时,应当先编排主办机关签发人职务、签名章,其余机关签发人职务、签名章依次向 下编排,与主办机关签发人职务、签名章上下对齐;每行只编排一个机关的签发人职务、签名章; 签发人职务应当标注全称。 签名章一般用红色。
二、编程实现落款排版
这里我们只考虑不加盖印章的公文的情况,而且不考虑联合行文。
要识别公文落款,我们同时对前后相邻两个段落文字p1和p2进行分析,首先,p1段末不含标点,
p2内容符合dddd年dd月dd日格式,其中d为阿拉伯数字。
我们首先利用正则表达式来判断给定字符串是否符合dddd年dd月dd日格式。代码如下:
//增:2023-07-16
//判断是否为dddd年dd月dd日格式
String.prototype.isDateCn = function()
{
//return (/^(\d{4})([\u5e74]{1})(\d{1,2})([\u6708]{1})\d{1,2}([\u65e5]{1})$/.test(this)); //年=\u5e74,月=\u6708,日=\u65e5
return (/^(\d{4})([年]{1})(\d{1,2})([月]{1})\d{1,2}([日]{1})$/.test(this)); //年=\u5e74,月=\u6708,日=\u65e5
}
//增:2023-07-16
//判断dddd年dd月dd日是否符合闰年等规则
String.prototype.isRightDateCn = function()
{
return (/^(?:(?!0000)[0-9]{4}([年]{1})(?:(?:0?[1-9]|1[0-2])\1(?:0?[1-9]|1[0-9]|2[0-8])|(?:0?[13-9]|1[0-2])\1(?:29|30)|(?:0?[13578]|1[02])\1(?:31))|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)([月]{1})0?2\2(?:29))([日]{1})$/.test(this));
}
在些基础上,我们编写isBadging()来判断相连两段文字是否为落款,代码如下:
//增:2023-07-16
//功能:判断是否为落款
//输入:t1:落款单位,t2:落款日期
//输出:true:是落款;false:非落款
function isBadging(t1,t2)
{
if (isAstatement(t1))//落款单位末尾是否带符号?
{
return false;//带符号,不是落款
}
return (t2.isDateCn());
}//isBadging(t1,t2)
如果确实是落款,我们要根据公文排版要求进行格式设置。首要需要计算出发文机关署名和成文日期的宽度,再进行比较。获取字符串宽度的方法有很多种,这里我们利用canvas.getContext().measureText().width来实现,代码如下:
//增:2023-07-22
//功能:利用canvas取字符串宽度
//输入:s:字符串,f:字体
//输出:字符串宽度
function getStrWidth(s, f)
{
//alert(s);
var canvas = getStrWidth.canvas || (getStrWidth.canvas = document.createElement("canvas"));
var ctx = canvas.getContext("2d");
ctx.font = f;
return ctx.measureText(s).width;
}//geStrWidth()
取得发文机关署名和成文日期的宽度后,我们就可以进行比较并根据比较结果来排版
比较难的是:
如成文日期长于发文机关署名,应当 使成文日期右空二字编排,并相应增加发文机关署名右空字数。
代码如下:
//增:2023-07-16,改2023-07-22
//功能:设置落款格式
//输入:t1:落款单位,t2:落款日期
//输出:格式化后的落款单位和落款日期代码
function setBadging(t1,t2)
{
var r = new Array();
var f = mtfs+ 'pt' + ' '+ mtfn;//顺序不能颠倒!
//noSeal
var iSize1 = getStrWidth(t1, f);
var iSize2 = getStrWidth(t2, f);
//document.write('' + iSize1 + " " + iSize2);
if (iSize2 > iSize1)
{
//如成文日期长于发文机关署名,应当使成文日期右空二字编排,并相应增加发文机关署名右空字数。
r[0] = '
' + t1;//1em=16px,2em=32px,3em=48px
r[1] = '
' + t2;
}
else
{
//单一机关行文时,在正文(或附件说明)下空一行右空二字编排发文机关署名,在发文机关署名下一行编排成文日期,首字比发文机关署名首字右移二字
r[0] = '
' + t1;
r[1] = '
' + t2;
}
return r.join('');
}//setBadging()
这里我们将格式化后的落款单位和落款日期代码合并成一个字符串了,那么setDocFmt()作相应的修改:
//功能:设置公文格式Set document format
//输入:无
//输出:无
function setDocFmt()
{
taDbg.value += "\n---setDocFmt()\n";
getArg();
var t = getClearInfoArray();
//标题
if (cbDocTilte)
{
t[0] = setDocTitle(t[0]) + ' ';
}
/*
for (var i = (cbDocTilte ? 1: 0); i < t.length; i++)
{
t[i] = setParaFmt(t[i]);
}
*/
var i = (cbDocTilte ? 1 : 0);//增:2023-07-16
while (i < t.length)
{
if (isBadging(t[i],t[i+1]))
{
//落款前加空行
t[i-1] += '
';
//设置落款
t[i] = setBadging(t[i],t[i+1]);
t[i+1] = null;
taDbg.value += "\nt[" + (i-1) + "]=" + t[i-1] + "\nt[" + i +"]=" + t[i] + "\nt[" +(i+1) +"]=" + t[i+1];
//i++;
//i++;
i += 2;
}
else
{
t[i] = setParaFmt(t[i]);
i++;
}
}//while()
alert(t.join(''));
edRichBody.innerHTML = t.join('');
}//setDocFmt()
三、程序运行效果
四、完整代码如下
公文一键排版系统
调试信息