|
|
|
|
using DSWeb.Areas.MvcShipping.DB;
|
|
|
|
|
using DSWeb.MvcShipping.Comm;
|
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
using org.apache.pdfbox.cos;
|
|
|
|
|
using org.apache.pdfbox.pdmodel;
|
|
|
|
|
using org.apache.pdfbox.pdmodel.common;
|
|
|
|
|
using org.apache.pdfbox.util;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Drawing;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Runtime.Caching;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Web;
|
|
|
|
|
using System.Web.Mvc;
|
|
|
|
|
|
|
|
|
|
namespace DSWeb.MvcShipping.Controllers
|
|
|
|
|
{
|
|
|
|
|
public class OcrController : Controller
|
|
|
|
|
{
|
|
|
|
|
private static readonly string ocrFilePath = "ocr_temp_files";
|
|
|
|
|
private static readonly string[] allowExts = new string[] { ".pdf", ".xls", ".xlsx", ".doc", ".docx",".rtf" };
|
|
|
|
|
//private static readonly int ImageScale = 1;
|
|
|
|
|
private static readonly int CacheExpire = 5;//缓存到期分钟
|
|
|
|
|
|
|
|
|
|
[HttpGet]
|
|
|
|
|
public ActionResult UpOcrAuto(string errMsg)
|
|
|
|
|
{
|
|
|
|
|
ViewData["errMsg"] = errMsg;
|
|
|
|
|
return View();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[HttpPost]
|
|
|
|
|
public ActionResult UpOcrFile(float scale = 1.5f)
|
|
|
|
|
{
|
|
|
|
|
if (Request.Files.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
var ext = Path.GetExtension(Request.Files[0].FileName).ToLower();
|
|
|
|
|
if (!allowExts.Contains(ext))
|
|
|
|
|
{
|
|
|
|
|
return RedirectToAction("UpOcrAuto", new { errMsg = "只能上传pdf、excel和word文件!" });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var ocrDir = Server.MapPath($"~/{ocrFilePath}");
|
|
|
|
|
if (!Directory.Exists(ocrDir))
|
|
|
|
|
{
|
|
|
|
|
Directory.CreateDirectory(ocrDir);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var tmpFileName = Guid.NewGuid().ToString();
|
|
|
|
|
var saveFilePathName = Path.Combine(ocrDir, tmpFileName + ext);
|
|
|
|
|
Request.Files[0].SaveAs(saveFilePathName);
|
|
|
|
|
|
|
|
|
|
if (ext == ".xls" || ext == ".xlsx")
|
|
|
|
|
{
|
|
|
|
|
Aspose.Cells.Workbook wb = new Aspose.Cells.Workbook(saveFilePathName);
|
|
|
|
|
string targetPath = Path.Combine(ocrDir, $"{tmpFileName}.pdf");
|
|
|
|
|
wb.Save(targetPath, Aspose.Cells.SaveFormat.Pdf);
|
|
|
|
|
}
|
|
|
|
|
else if (ext == ".doc" || ext == ".docx" || ext == ".rtf")
|
|
|
|
|
{
|
|
|
|
|
Aspose.Words.Document doc = new Aspose.Words.Document(saveFilePathName);
|
|
|
|
|
string targetPath = Path.Combine(ocrDir, $"{tmpFileName}.pdf");
|
|
|
|
|
doc.Save(targetPath, Aspose.Words.SaveFormat.Pdf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ReadPdf(tmpFileName, scale);
|
|
|
|
|
|
|
|
|
|
#region 挂载到单据管理
|
|
|
|
|
var BSNO = Request.Form["BSNO"];
|
|
|
|
|
var CUSTID = Guid.NewGuid().ToString();
|
|
|
|
|
var path = Server.MapPath("../../UploadFiles/MsOpFiles/" + CUSTID);
|
|
|
|
|
|
|
|
|
|
if (!Directory.Exists(path))
|
|
|
|
|
{
|
|
|
|
|
Directory.CreateDirectory(path);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var size = Request.Files[0].ContentLength;
|
|
|
|
|
var name = Path.GetFileName(Request.Files[0].FileName);
|
|
|
|
|
|
|
|
|
|
var usercode = Convert.ToString(Session["USERCODE"]);
|
|
|
|
|
var partname = usercode + DateTime.Now.ToString("yyyyMMddHHmmssfff") + name;
|
|
|
|
|
string filename = path + "\\" + partname;
|
|
|
|
|
string filenameURL = "../../UploadFiles/MsOpFiles/" + CUSTID + "/" + partname;
|
|
|
|
|
if (System.IO.File.Exists(filename))
|
|
|
|
|
{
|
|
|
|
|
System.IO.File.Delete(filename);
|
|
|
|
|
}
|
|
|
|
|
Request.Files[0].SaveAs(filename);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ReceiptContext receiptContext = new ReceiptContext();
|
|
|
|
|
Receipt_Doc recDoc = new Receipt_Doc();
|
|
|
|
|
recDoc.GID = Guid.NewGuid().ToString();
|
|
|
|
|
recDoc.BSNO = BSNO;
|
|
|
|
|
recDoc.URL = name;
|
|
|
|
|
recDoc.Driect_URL = filenameURL;
|
|
|
|
|
recDoc.MODIFIEDUSER = Convert.ToString(Session["USERID"]);
|
|
|
|
|
recDoc.MODIFIEDTIME = DateTime.Now;
|
|
|
|
|
recDoc.RECEIPTTYPE = string.Empty;
|
|
|
|
|
recDoc.documentAttachedCode = string.Empty;
|
|
|
|
|
recDoc.documentAttachedNo = string.Empty;
|
|
|
|
|
receiptContext.ReceiptDocs.Add(recDoc);
|
|
|
|
|
receiptContext.SaveChanges();
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return RedirectToAction("SelectRegion", new { fileName = tmpFileName });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return RedirectToAction("UpOcrAuto");
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[HttpGet]
|
|
|
|
|
public ActionResult SelectRegion(string fileName)
|
|
|
|
|
{
|
|
|
|
|
ViewData["FileName"] = fileName;
|
|
|
|
|
return View();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[HttpPost]
|
|
|
|
|
public ContentResult GetRegionText(string fileName, int x, int y, int w, int h, float scale = 1.5f)
|
|
|
|
|
{
|
|
|
|
|
if (!MemoryCache.Default.Contains(fileName))
|
|
|
|
|
{
|
|
|
|
|
ReadPdf(fileName, scale);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dynamic obj = MemoryCache.Default[fileName];
|
|
|
|
|
if (obj != null)
|
|
|
|
|
{
|
|
|
|
|
Rectangle rectMouse = new Rectangle(x, y, w, h);
|
|
|
|
|
List<TextSizeLocation> listTextLocations = obj.Result;
|
|
|
|
|
Size size = obj.Size;
|
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
|
int lastY = 0;
|
|
|
|
|
foreach (var item in listTextLocations)
|
|
|
|
|
{
|
|
|
|
|
int xItem = (int)(item.X * scale);
|
|
|
|
|
int yItem = (int)(size.Height * scale - item.Y * scale);
|
|
|
|
|
int wItem = (int)(item.Width * scale);
|
|
|
|
|
int hItem = (int)(item.Height * scale);
|
|
|
|
|
|
|
|
|
|
Rectangle rect = new Rectangle(xItem, yItem, wItem, hItem);
|
|
|
|
|
|
|
|
|
|
if (rect.IntersectsWith(rectMouse))
|
|
|
|
|
{
|
|
|
|
|
if (lastY != 0 && Math.Abs(lastY - item.Y) > 1)
|
|
|
|
|
{
|
|
|
|
|
sb.AppendLine();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sb.Append(item.Text);
|
|
|
|
|
|
|
|
|
|
lastY = (int)item.Y;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Content(sb.ToString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Content("");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[HttpGet]
|
|
|
|
|
public ActionResult GetCanvasImage(string fileName, float scale = 1.5f)
|
|
|
|
|
{
|
|
|
|
|
var ocrDir = Server.MapPath($"~/{ocrFilePath}");
|
|
|
|
|
var imgPath = Path.Combine(ocrDir, $"{fileName}_{scale}.jpg");
|
|
|
|
|
if (!System.IO.File.Exists(imgPath))
|
|
|
|
|
{
|
|
|
|
|
dynamic obj = MemoryCache.Default[fileName];
|
|
|
|
|
if (obj != null)
|
|
|
|
|
{
|
|
|
|
|
Size size = obj.Size;
|
|
|
|
|
DrawImg((int)(size.Width * scale), (int)(size.Height * scale), fileName, scale);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (System.IO.File.Exists(imgPath))
|
|
|
|
|
{
|
|
|
|
|
return File(imgPath, "image/jpg");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ReadPdf(string fileName, float scale)
|
|
|
|
|
{
|
|
|
|
|
var ocrDir = Server.MapPath($"~/{ocrFilePath}");
|
|
|
|
|
var pdfFileName = System.IO.Path.Combine(ocrDir, fileName + ".pdf");
|
|
|
|
|
|
|
|
|
|
if (!System.IO.File.Exists(pdfFileName))
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PDDocument document = PDDocument.load(pdfFileName);
|
|
|
|
|
PrintTextLocations printer = new PrintTextLocations();
|
|
|
|
|
java.util.List allPages = document.getDocumentCatalog().getAllPages();
|
|
|
|
|
PDPage page = (PDPage)allPages.get(0);
|
|
|
|
|
PDStream contents = page.getContents();
|
|
|
|
|
if (contents != null)
|
|
|
|
|
{
|
|
|
|
|
printer.processStream(page, page.findResources(), page.getContents().getStream());
|
|
|
|
|
|
|
|
|
|
//处理
|
|
|
|
|
var listT = new List<TextSizeLocation>();
|
|
|
|
|
TextSizeLocation t = null;
|
|
|
|
|
foreach (var item in printer.TextWithLocations)
|
|
|
|
|
{
|
|
|
|
|
if (t == null)
|
|
|
|
|
{
|
|
|
|
|
t = item.Clone();
|
|
|
|
|
listT.Add(t);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
if (Math.Abs(t.Width + t.X - item.X) <= item.Width / 2 && Math.Abs(t.Height - item.Height) <= 1) //首尾相接
|
|
|
|
|
{
|
|
|
|
|
t.Width += item.Width;
|
|
|
|
|
t.Text += item.Text;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
t = item.Clone();
|
|
|
|
|
listT.Add(t);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var query = from it in listT orderby it.Y descending, it.X select it;
|
|
|
|
|
listT = query.ToList();
|
|
|
|
|
|
|
|
|
|
//缓存
|
|
|
|
|
MemoryCache.Default.Remove(fileName);
|
|
|
|
|
var objStore = new { Size = new Size((int)page.findCropBox().getWidth(), (int)page.findCropBox().getHeight()), Result = listT };
|
|
|
|
|
MemoryCache.Default.Add(new CacheItem(fileName, objStore), new CacheItemPolicy() { AbsoluteExpiration = new DateTimeOffset(DateTime.Now.AddMinutes(CacheExpire)) });
|
|
|
|
|
|
|
|
|
|
DrawImg((int)(page.findCropBox().getWidth() * scale), (int)(page.findCropBox().getHeight() * scale), fileName, scale);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
document.close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void DrawImg(int width, int height, string fileName, float scale)
|
|
|
|
|
{
|
|
|
|
|
var ocrDir = Server.MapPath($"~/{ocrFilePath}");
|
|
|
|
|
Bitmap bitmap = new Bitmap(width, height);
|
|
|
|
|
Graphics graphics = Graphics.FromImage(bitmap);
|
|
|
|
|
graphics.Clear(Color.White);
|
|
|
|
|
|
|
|
|
|
dynamic obj = MemoryCache.Default[fileName];
|
|
|
|
|
if (obj != null)
|
|
|
|
|
{
|
|
|
|
|
List<TextSizeLocation> listTextLocations = obj.Result;
|
|
|
|
|
Size size = obj.Size;
|
|
|
|
|
|
|
|
|
|
Random rnd = new Random();
|
|
|
|
|
foreach (var item in listTextLocations)
|
|
|
|
|
{
|
|
|
|
|
float textSize = GetMatchTextSize(item.Width * scale, item.Height * scale, item.Text);
|
|
|
|
|
graphics.DrawString(item.Text, new Font("黑体", textSize), Brushes.Black, item.X * scale, bitmap.Height - item.Y * scale);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var imgPath = Path.Combine(ocrDir, $"{fileName}_{scale}.jpg");
|
|
|
|
|
bitmap.Save(imgPath);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private float GetMatchTextSize(float width, float height, string str)
|
|
|
|
|
{
|
|
|
|
|
float plus = 0.1f;
|
|
|
|
|
float rtn = 1;
|
|
|
|
|
Bitmap bm = new Bitmap(1, 1);
|
|
|
|
|
Graphics g = Graphics.FromImage(bm);
|
|
|
|
|
for (float i = 1; i < 100; i += plus)
|
|
|
|
|
{
|
|
|
|
|
var font = new Font("黑体", i);
|
|
|
|
|
SizeF size = g.MeasureString(str, font);
|
|
|
|
|
//if (size.Width > width || size.Height > height)
|
|
|
|
|
if (size.Width > width)
|
|
|
|
|
//if (size.Height > height)
|
|
|
|
|
{
|
|
|
|
|
if (i > 1)
|
|
|
|
|
{
|
|
|
|
|
rtn = i - plus;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rtn;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class TextSizeLocation
|
|
|
|
|
{
|
|
|
|
|
public TextSizeLocation() { }
|
|
|
|
|
|
|
|
|
|
public TextSizeLocation(float x, float y, float width, float height, string text)
|
|
|
|
|
{
|
|
|
|
|
this.X = x;
|
|
|
|
|
this.Y = y;
|
|
|
|
|
this.Width = width;
|
|
|
|
|
this.Height = height;
|
|
|
|
|
this.Text = text;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public float X { get; set; }
|
|
|
|
|
public float Y { get; set; }
|
|
|
|
|
public float Width { get; set; }
|
|
|
|
|
public float Height { get; set; }
|
|
|
|
|
public string Text { get; set; }
|
|
|
|
|
|
|
|
|
|
public TextSizeLocation Clone()
|
|
|
|
|
{
|
|
|
|
|
return new TextSizeLocation()
|
|
|
|
|
{
|
|
|
|
|
X = this.X,
|
|
|
|
|
Y = this.Y,
|
|
|
|
|
Width = this.Width,
|
|
|
|
|
Height = this.Height,
|
|
|
|
|
Text = this.Text
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class PrintTextLocations : PDFTextStripper
|
|
|
|
|
{
|
|
|
|
|
public List<TextSizeLocation> TextWithLocations { get; set; }
|
|
|
|
|
public List<TextPosition> TextPositions { get; set; }
|
|
|
|
|
|
|
|
|
|
public PrintTextLocations()
|
|
|
|
|
{
|
|
|
|
|
this.TextWithLocations = new List<TextSizeLocation>();
|
|
|
|
|
this.TextPositions = new List<TextPosition>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void processStream(PDPage aPage, PDResources resources, COSStream cosStream)
|
|
|
|
|
{
|
|
|
|
|
this.TextWithLocations.Clear();
|
|
|
|
|
this.TextPositions.Clear();
|
|
|
|
|
base.processStream(aPage, resources, cosStream);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void processTextPosition(TextPosition text)
|
|
|
|
|
{
|
|
|
|
|
this.TextPositions.Add(text);
|
|
|
|
|
this.TextWithLocations.Add(new TextSizeLocation(text.getTextPos().getXPosition(), text.getTextPos().getYPosition(), text.getWidth(), text.getHeight(), text.getCharacter()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|