feixian_weifajianguan/OpenAuth.App/Common/MiWordHelper.cs

343 lines
16 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using Microsoft.AspNetCore.Hosting;
using OpenAuth.Repository.Domain;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OpenAuth.App.Common
{
public class MiWordHelper
{
#region
public string GenerateSeizureDocumentWord(MiSeizureDocument mr, IWebHostEnvironment env)
{
string templatePath = Path.Combine(env.ContentRootPath, "Templates", "扣押财物决定书.docx");
if (!File.Exists(templatePath))
throw new FileNotFoundException("模板文件不存在", templatePath);
string fileName = $"扣押财物决定书_{mr.Id}.docx";
string uploadDir = Path.Combine(env.ContentRootPath, "upload");
if (!Directory.Exists(uploadDir))
Directory.CreateDirectory(uploadDir);
string outputPath = Path.Combine(uploadDir, fileName);
File.Copy(templatePath, outputPath, true);
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(outputPath, true))
{
Body body = wordDoc.MainDocumentPart.Document.Body;
ReplacePlaceholders(body, mr);
wordDoc.MainDocumentPart.Document.Save();
}
return $"/upload/{fileName}";
}
private void ReplacePlaceholders(Body body, MiSeizureDocument mr)
{
// 准备替换值
string party = mr.Party ?? "";
string clueLocation = mr.ClueLocation ?? "";
string violationType = mr.ViolationType ?? "";
string year = mr.Year ?? DateTime.Now.Year.ToString();
string serialNumber = mr.SerialNumber.ToString("D3");
int month = mr.SeizureDate?.Month ?? 0;
int day = mr.SeizureDate?.Day ?? 0;
string monthStr = month > 0 ? month.ToString() : "";
string dayStr = day > 0 ? day.ToString() : "";
var paragraphs = body.Elements<Paragraph>().ToList();
for (int i = 0; i < paragraphs.Count; i++)
{
Paragraph para = paragraphs[i];
string paraText = para.InnerText;
// 处理物品列表占位符 {{Items}}
if (paraText.Contains("{{Items}}"))
{
ParagraphProperties paraProps = para.ParagraphProperties?.CloneNode(true) as ParagraphProperties;
var runs = para.Elements<Run>().ToList();
RunProperties indexRunProps = null; // 序号部分的样式
RunProperties contentRunProps = null; // 内容部分的样式
// 找到包含 "{{Items}}" 的 Run 作为内容 Run
Run contentRun = runs.FirstOrDefault(r => r.InnerText.Contains("{{Items}}"));
if (contentRun?.RunProperties != null)
contentRunProps = contentRun.RunProperties.CloneNode(true) as RunProperties;
// 取第一个 Run 作为序号 Run假设序号在最前面
Run indexRun = runs.FirstOrDefault();
if (indexRun != null && indexRun != contentRun && indexRun.RunProperties != null)
indexRunProps = indexRun.RunProperties.CloneNode(true) as RunProperties;
para.Remove();
InsertItemsParagraphs(body, i, mr.Items, paraProps, indexRunProps, contentRunProps);
ReplacePlaceholders(body, mr); // 重新开始循环
return;
}
// 处理普通占位符替换
foreach (var run in para.Elements<Run>())
{
Text text = run.Elements<Text>().FirstOrDefault();
if (text == null) continue;
string original = text.Text;
string replaced = original
.Replace("{{Party}}", party)
.Replace("{{ClueLocation}}", clueLocation)
.Replace("{{Year}}", year)
.Replace("{{Month}}", monthStr)
.Replace("{{Day}}", dayStr)
.Replace("{{SerialNumber}}", serialNumber)
.Replace("{{ViolationType}}", violationType); // 方括号形式
if (original != replaced)
text.Text = replaced;
}
}
}
private void InsertItemsParagraphs(Body body, int insertIndex, string itemsStr,
ParagraphProperties templateParaProps,
RunProperties indexRunProps,
RunProperties contentRunProps)
{
string[] items = itemsStr.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < items.Length; i++)
{
string indexText = $"{i + 1}、 ";
string rawContent = items[i].Trim();
int leadingSpaces = 6;
int trailingSpaces = 30 - leadingSpaces - rawContent.Length;
if (trailingSpaces < 0) trailingSpaces = 0;
string contentText = new string(' ', leadingSpaces) + rawContent + new string(' ', trailingSpaces);
Paragraph newPara = new Paragraph();
if (templateParaProps != null)
newPara.ParagraphProperties = (ParagraphProperties)templateParaProps.CloneNode(true);
// 序号 Run移除可能的下划线
Run indexRun = new Run();
if (indexRunProps != null)
{
indexRun.RunProperties = (RunProperties)indexRunProps.CloneNode(true);
if (indexRun.RunProperties.Underline != null)
indexRun.RunProperties.Underline.Remove();
}
// 关键:设置 Space 为 Preserve 以保留空格
indexRun.AppendChild(new Text(indexText) { Space = SpaceProcessingModeValues.Preserve });
newPara.AppendChild(indexRun);
// 内容 Run强制黑色下划线
Run contentRun = new Run();
if (contentRunProps != null)
{
contentRun.RunProperties = (RunProperties)contentRunProps.CloneNode(true);
if (contentRun.RunProperties.Color == null)
contentRun.RunProperties.Color = new Color() { Val = "000000" };
else
contentRun.RunProperties.Color.Val = "000000";
if (contentRun.RunProperties.Underline == null)
contentRun.RunProperties.Underline = new Underline() { Val = UnderlineValues.Single };
}
else
{
contentRun.RunProperties = new RunProperties();
contentRun.RunProperties.Underline = new Underline() { Val = UnderlineValues.Single };
contentRun.RunProperties.Color = new Color() { Val = "000000" };
}
// 关键:设置 Space 为 Preserve 以保留前后空格
contentRun.AppendChild(new Text(contentText) { Space = SpaceProcessingModeValues.Preserve });
newPara.AppendChild(contentRun);
body.InsertAt(newPara, insertIndex + i);
}
}
#endregion
#region 解除扣押
public string GenerateReleaseDocumentWord(MiReleaseDocument rd, IWebHostEnvironment env)
{
string templatePath = Path.Combine(env.ContentRootPath, "Templates", "解除扣押决定书.docx");
if (!File.Exists(templatePath))
throw new FileNotFoundException("模板文件不存在", templatePath);
string fileName = $"解除扣押决定书_{rd.Id}.docx";
string uploadDir = Path.Combine(env.ContentRootPath, "upload");
if (!Directory.Exists(uploadDir))
Directory.CreateDirectory(uploadDir);
string outputPath = Path.Combine(uploadDir, fileName);
File.Copy(templatePath, outputPath, true);
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(outputPath, true))
{
Body body = wordDoc.MainDocumentPart.Document.Body;
ReplacePlaceholdersForRelease(body, rd);
wordDoc.MainDocumentPart.Document.Save();
}
return $"/upload/{fileName}";
}
private void ReplacePlaceholdersForRelease(Body body, MiReleaseDocument rd)
{
// 准备替换值
string party = rd.Party ?? "";
string clueLocation = rd.ClueLocation ?? "";
string violationType = rd.ViolationType ?? "";
string year = rd.Year ?? DateTime.Now.Year.ToString();
string serialNumber = rd.SerialNumber.ToString("D3");
// 解除扣押决定日期(落款)
int rYear = rd.ReleaseDate?.Year ?? 0;
int rMonth = rd.ReleaseDate?.Month ?? 0;
int rDay = rd.ReleaseDate?.Day ?? 0;
string rYearStr = rYear > 0 ? rYear.ToString() : "";
string rMonthStr = rMonth > 0 ? rMonth.ToString() : "";
string rDayStr = rDay > 0 ? rDay.ToString() : "";
// 领取截止日期
int pYear = rd.PickupDeadline?.Year ?? 0;
int pMonth = rd.PickupDeadline?.Month ?? 0;
int pDay = rd.PickupDeadline?.Day ?? 0;
string pYearStr = pYear > 0 ? pYear.ToString() : "";
string pMonthStr = pMonth > 0 ? pMonth.ToString() : "";
string pDayStr = pDay > 0 ? pDay.ToString() : "";
// 扣押财物日期(来自实体类 SeizureData
int fYear = rd.SeizureData?.Year ?? 0;
int fMonth = rd.SeizureData?.Month ?? 0;
int fDay = rd.SeizureData?.Day ?? 0;
string fYearStr = fYear > 0 ? fYear.ToString() : "";
string fMonthStr = fMonth > 0 ? fMonth.ToString() : "";
string fDayStr = fDay > 0 ? fDay.ToString() : "";
string parkingLot = rd.ParkingLot ?? "";
var paragraphs = body.Elements<Paragraph>().ToList();
for (int i = 0; i < paragraphs.Count; i++)
{
Paragraph para = paragraphs[i];
string paraText = para.InnerText;
// 处理物品列表占位符 {{Items}}
if (paraText.Contains("{{Items}}"))
{
ParagraphProperties paraProps = para.ParagraphProperties?.CloneNode(true) as ParagraphProperties;
var runs = para.Elements<Run>().ToList();
RunProperties indexRunProps = null;
RunProperties contentRunProps = null;
// 找到包含 "{{Items}}" 的 Run 作为内容 Run
Run contentRun = runs.FirstOrDefault(r => r.InnerText.Contains("{{Items}}"));
if (contentRun?.RunProperties != null)
contentRunProps = contentRun.RunProperties.CloneNode(true) as RunProperties;
// 取第一个 Run 作为序号 Run假设序号在最前面
Run indexRun = runs.FirstOrDefault();
if (indexRun != null && indexRun != contentRun && indexRun.RunProperties != null)
indexRunProps = indexRun.RunProperties.CloneNode(true) as RunProperties;
para.Remove();
InsertItemsParagraphs(body, i, rd.Items, paraProps, indexRunProps, contentRunProps);
ReplacePlaceholdersForRelease(body, rd); // 重新开始循环
return;
}
// 处理普通占位符替换
foreach (var run in para.Elements<Run>())
{
Text text = run.Elements<Text>().FirstOrDefault();
if (text == null) continue;
string original = text.Text;
string replaced = original
.Replace("{{Year}}", year) // 文书编号年份
.Replace("{{SerialNumber}}", serialNumber)
.Replace("{{Paty}}", party) // 注意模板拼写为 Paty
.Replace("{{ClueLocation}}", clueLocation)
.Replace("{{ViolationType}}", violationType)
.Replace("{{FYear}}", fYearStr)
.Replace("{{FMonth}}", fMonthStr)
.Replace("{{FDay}}", fDayStr)
.Replace("{{PYear}}", pYearStr)
.Replace("{{Pmonth}}", pMonthStr) // 注意大小写
.Replace("{{Pday}}", pDayStr)
.Replace("{{ParkingLot}}", parkingLot)
.Replace("{{Month}}", rMonthStr) // 落款月份
.Replace("{{Day}}", rDayStr); // 落款日
if (original != replaced)
text.Text = replaced;
}
}
}
//private void InsertItemsParagraphs(Body body, int insertIndex, string itemsStr,
// ParagraphProperties templateParaProps,
// RunProperties indexRunProps,
// RunProperties contentRunProps)
//{
// string[] items = itemsStr.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
// for (int i = 0; i < items.Length; i++)
// {
// string indexText = $"{i + 1}、 ";
// string rawContent = items[i].Trim();
// int leadingSpaces = 6;
// int trailingSpaces = 30 - leadingSpaces - rawContent.Length;
// if (trailingSpaces < 0) trailingSpaces = 0;
// string contentText = new string(' ', leadingSpaces) + rawContent + new string(' ', trailingSpaces);
// Paragraph newPara = new Paragraph();
// if (templateParaProps != null)
// newPara.ParagraphProperties = (ParagraphProperties)templateParaProps.CloneNode(true);
// // 序号 Run移除可能的下划线
// Run indexRun = new Run();
// if (indexRunProps != null)
// {
// indexRun.RunProperties = (RunProperties)indexRunProps.CloneNode(true);
// if (indexRun.RunProperties.Underline != null)
// indexRun.RunProperties.Underline.Remove();
// }
// // 关键:设置 Space 为 Preserve 以保留空格
// indexRun.AppendChild(new Text(indexText) { Space = SpaceProcessingModeValues.Preserve });
// newPara.AppendChild(indexRun);
// // 内容 Run强制黑色下划线
// Run contentRun = new Run();
// if (contentRunProps != null)
// {
// contentRun.RunProperties = (RunProperties)contentRunProps.CloneNode(true);
// if (contentRun.RunProperties.Color == null)
// contentRun.RunProperties.Color = new Color() { Val = "000000" };
// else
// contentRun.RunProperties.Color.Val = "000000";
// if (contentRun.RunProperties.Underline == null)
// contentRun.RunProperties.Underline = new Underline() { Val = UnderlineValues.Single };
// }
// else
// {
// contentRun.RunProperties = new RunProperties();
// contentRun.RunProperties.Underline = new Underline() { Val = UnderlineValues.Single };
// contentRun.RunProperties.Color = new Color() { Val = "000000" };
// }
// // 关键:设置 Space 为 Preserve 以保留前后空格
// contentRun.AppendChild(new Text(contentText) { Space = SpaceProcessingModeValues.Preserve });
// newPara.AppendChild(contentRun);
// body.InsertAt(newPara, insertIndex + i);
// }
//}
#endregion
}
}