【问题标题】:Javascript- Stamping on pdf page is out of positionJavascript- pdf 页面上的图章不在位置
【发布时间】:2018-09-20 10:49:26
【问题描述】:

我正在开发一个程序,当我启动它时,它会将我目录中的 pdf 文件加载到 Web 浏览器。在浏览器中,我可以选择单击图章并拖动并移动到我想要的任何位置并将其标记在 pdf 上。但是,一旦我盖上它,印章的位置就不是我想要的了。

以下是示例快照:

下面是粘贴后的输出(这不是我想要的):

Javascript:

function divMove(e){
        var div = document.getElementById('stamp');
        div.style.position = 'absolute';
        //div.style.top = e.clientY + 'px';
        //div.style.left = e.clientX + 'px';
        var box = div.getBoundingClientRect();
        mouse_top = e.clientY;
        mouse_left = e.clientX;
        var diff_x = mouse_left - box.left;
        var diff_y = mouse_top - box.top;
        div.style.top = ((Number(div.style.top.replace("px", "")) - 1) + diff_y) +"px";
        div.style.left = ((Number(div.style.left.replace("px", "")) - 1) + diff_x) +"px";
        document.getElementById("data").innerHTML =
            "mouse_top:" + mouse_top + "<br>mouse_left:" + mouse_left
    }

    function save(){
        $.ajax({
            type: "GET",
            url: "Save",
            data: {
                mouseTop : (mouse_top/96)*1,
                mouseLeft : (mouse_left/96)*3500
            },
            dataType: "text",
            success: function (response) {
            //use response to set stamp
                if (response != null) {
                    var pdfAsArray = convertDataURIToBinary("data:application/pdf;base64, " + response);
                    loadPDFToViewer(pdfAsArray);
                    //document.getElementById("page-1").getElementsByClassName("pdfCanvas")[0].removeEventListener("click", addStamp);
                } else {
                    alert("Response is null");
                }
            }
        });
    }

后端(java):

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        //String src = "C:\\Apache Tomcat\\apache-tomcat-7.0.78\\myWork\\prototype\\haito.pdf";
        //String dest = "C:\\Apache Tomcat\\apache-tomcat-7.0.78\\myWork\\prototype\\test.pdf";

        Properties p = new Properties();
        p.load(new FileInputStream("config.properties"));

        String src = p.getProperty("src");
        String dest = p.getProperty("dest");
        String imgSrc = p.getProperty("stamp");

        PdfDocument doc = new PdfDocument(new PdfReader(src), new PdfWriter(dest));


        ImageData image = ImageDataFactory.create(imgSrc);

        float w = image.getWidth();
        float h = image.getHeight();
        System.out.println("w: " + w + ", h: " + h);





        float mouseX = Float.valueOf(request.getParameter("mouseTop"));
        float mouseY = Float.valueOf(request.getParameter("mouseLeft"));
        System.out.println("top: " + mouseX + ", left: " + mouseY);
        //  adjusted mouse X and mouse Y position




        Rectangle rect = new Rectangle(mouseX ,mouseY  ,w,h);
        PdfStampAnnotation stamp = new PdfStampAnnotation(rect).setStampName(new PdfName("Approved"));
        PdfFormXObject xObj = new PdfFormXObject(new Rectangle(w,h));
        PdfCanvas canvas = new PdfCanvas(xObj,doc);
        canvas.addImage(image,0,0,false);

        //canvas.getGraphicsState();
        stamp.setNormalAppearance(xObj.getPdfObject());
        stamp.setFlags(PdfAnnotation.PRINT);
        stamp.setFlags(PdfAnnotation.LOCKED);
        for(int i=1;i<=doc.getNumberOfPages();i++)
        {
            doc.getPage(i).addAnnotation(stamp);
        }
        //doc.getFirstPage().addAnnotation(stamp);
        FileOutputStream out = new FileOutputStream("config.properties");
        p.setProperty("src", dest);
        p.setProperty("dest", src);
        p.store(out, null);
        out.close();
        doc.close();

我已经在这个问题上苦苦挣扎了好几天。我将不胜感激任何形式的帮助。 有没有办法让位置准确?

【问题讨论】:

  • 欢迎来到 StackOverflow!您能否分享根据您的 AJAX 输入标记 PDF 的后端代码?您的问题可能出在后端使用鼠标坐标的方式上。
  • @davidethell 好的,我编辑了我的帖子
  • @Liam 后端部分是用 Java 编写的。我正在为 PDF 部分使用 iText 库。

标签: javascript java pdf itext7


【解决方案1】:

您的 canvas.addImage 调用传递 0, 0 作为 x 和 y 坐标。相反,您应该从鼠标坐标传递正确翻译的坐标。请记住,在 PDF 中,所有内容都是从底部计算的,因此 y = 0 是页面底部,而不是顶部。

此外,使用 iText 中的一些示例(如您在此处找到)可能有更好的标记方法:https://developers.itextpdf.com/question/how-stamp-image-existing-pdf-and-create-anchor

PdfReader readerOriginalDoc = new PdfReader("src/main/resources/test.pdf");            
PdfStamper stamper = new PdfStamper(
    readerOriginalDoc, new FileOutputStream("NewStamper.pdf"));
PdfContentByte content = stamper.getOverContent(1);
Image image = Image.getInstance("src/main/resources/images.jpg");
image.scaleAbsolute(50, 20);
image.setAbsolutePosition(100, 100);
image.setAnnotation(new Annotation(0, 0, 0, 0, 3));
content.addImage(image);
stamper.close();

更新: 下面是一个关于根据报告的浏览器定位决定 PDF 定位的示例:

docHeight = something; // however you choose to find the height of your document area
docWidth = something; // however you choose to find the width of your document area
mouse_top = e.clientY;
mouse_left = e.clientX;
percentTop = mouse_top / docHeight;
percentLeft = mouse_left / docWidth;

更新:宽度和高度可能是您的标记或整个文档中的特定元素。所以你可以这样得到宽度和高度:

var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
var h = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;

现在将这些百分比传递给后端,您可以反向查找 PDF 坐标:

float percentBottom = 100.0 - Float.valueOf(request.getParameter("percentTop"));
float percentLeft = Float.valueOf(request.getParameter("percentLeft"));

底部现在转换为您需要从页面底部上升多少百分比才能获得正确的顶部位置。左边的位置应该是相同的百分比。我希望这会有所帮助。

【讨论】:

  • 我之前查看过链接。不幸的是,PDFStamper 对最新的 iText 版本不再有效。
  • 所以我只需要更改画布的正确坐标就可以解决我的问题了吗?
  • 好吧,确定鼠标坐标和PDF坐标之间的转换是您的关键。我很确定您想尝试使用百分比。因此,如果您的 Y 距离顶部为 50,那么在浏览器上可能是距离顶部 20% 的位置,那么将您的图章从底部的 80% 放置在 PDF 上。希望这是有道理的。
  • 你能举个例子说明你对 % 的意思吗?
  • “请记住,在 PDF 中,所有内容都是从底部开始计算的,因此 y = 0 是页面底部,而不是顶部。” - 通常情况如此。但是,一般来说,原点可以位于可见页面区域内部或外部的任何位置。所以总的来说,计算要多一点。
猜你喜欢
  • 2012-01-18
  • 1970-01-01
  • 2019-01-20
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
  • 2014-09-18
  • 1970-01-01
相关资源
最近更新 更多