前端pdf合并,删除,增加页数等对pdf修改的解决方法

对pdf修改主要使用pdf.js和pdf-lib这两个库
首先使用pdf.js对文件进行预览

<iframe ref="iframe" style="width: 100%; height: 99.4%"
            :src="'/pdf/web/viewer.html'" class="iframeClass" frameborder="0"
            seamless allowfullscreen="false">
          </iframe>

然后再引入自己封装的对pdf操作的文件

import { PDFLibEditor } from "./../../../public/plugins/web/pdflib-editor";

pdflib-editor文件内容如下

import { PDFDocument, rgb, degrees } from 'pdf-lib'
// import html2pdf from "html2pdf.js"
// console.log(html2pdf)
/**
 * 根据字符串生成页面数组
 * @param pageNumStr
 * @returns {*[]}
 */
function getPages(pageNumStr) {
    if (!pageNumStr) {
        console.error("page number string: ", pageNumStr)
        return []
    }
    const srcPageNum = pageNumStr.split(',')
    const resultPageNum = []
    const reg = /[\t\r\f\n\s]*/g
    srcPageNum.forEach(num => {
        if (/^[1-9]\d*$/g.test(num)) {
            resultPageNum.push(parseInt(num.replace(reg, '')))
        } else if (/^([1-9]\d*\s*-\s*[1-9]\d*)*$/g.test(num)) {
            const tmpArray = num.split('-')
            const a = tmpArray[0].replace(reg, '')
            const b = tmpArray[1].replace(reg, '')
            const start = Math.min(a, b)
            const end = Math.max(a, b)
            for (let i = start; i <= end; i++) {
                resultPageNum.push(i)
            }
        } else {
            console.error("page number format error:", num)
        }
    })
    resultPageNum.sort((a, b) => b - a)
    return resultPageNum
}

/**
 * 计算页码开始坐标
 * @param position 页码位置
 * @param width pdf page 宽度
 * @param height pdf page 高度
 * @param charNum 字符数个数
 */
function computePosition(position, width, height, charNum) {

    let x, y
    if (position == 1) {
        x = 20
        y = height - 22
        return { x, y }
    } else if (position == 2) {
        x = (width - charNum * 12) / 2
        y = height - 22
        return { x, y }

    } else if (position == 3) {
        x = width - charNum * 12 - 10
        y = height - 22
        return { x, y }

    } else if (position == 4) {
        x = 20
        y = 10
        return { x, y }

    } else if (position == 5) {
        x = (width - charNum * 12) / 2
        y = 10
        return { x, y }

    } else if (position == 6) {
        x = width - charNum * 12 - 10
        y = 10
        return { x, y }

    }

}
/**
     * 处理拆分页数
     */
function splitList(a, b) {
    var d = []
    if (a[0] != 1 && (a[1] != ',' || a[1] != '-')) {
        a = "1-" + String(Number(a.split(',')[0].split('-')[0]) - 1) + "," + a
    }
    if (a.indexOf(String(b)) == -1) {

        if (a.split(',')[a.split(',').length - 1].indexOf('-') > -1) {
            a = a + ',' + String(Number(a.split(',')[a.split(',').length - 1].split("-")[1]) + 1) + '-' + String(b)
        } else {

            a = a + ',' + String(Number(a.split(',')[a.split(',').length - 1]) + 1) + '-' + String(b)
        }
    }
    var c = a.split(',')
    console.log(a)
    c.map((item, index) => {
        if (item.indexOf('-') > -1) {
            let e = []
            let f = []
            if (c[index - 1]) {
                if (c[index - 1].indexOf('-') > -1) {
                    if (Number(c[index - 1].split('-')[1]) + 1 != Number(item.split('-')[0])) {
                        for (let x = Number(c[index - 1].split('-')[1]) + 1; x < Number(item.split('-')[0]); x++) {
                            e.push(x)
                        }
                        d.push(e)
                    }
                } else {
                    if (Number(item.split('-')[0]) > Number(c[index - 1]) + 1) {
                        for (let x = Number(c[index - 1]) + 1; x < Number(item.split('-')[0]); x++) {
                            e.push(x)
                        }
                        d.push(e)
                    }
                }
                for (let x = Number(item.split('-')[0]); x <= Number(item.split('-')[1]); x++) {
                    f.push(x)
                }

            } else {
                for (let x = Number(item.split('-')[0]); x <= Number(item.split('-')[1]); x++) {
                    f.push(x)
                }

            }


            d.push(f)
        } else {
            if (c[index - 1] && c[index - 1].indexOf('-') > -1) {
                let e = []
                if (Number(item) > Number(c[index - 1].split('-')[1]) + 1) {
                    for (let x = Number(c[index - 1].split('-')[1]) + 1; x < Number(item); x++) {
                        e.push(x)
                    }
                    d.push(e)
                }
            } else {
                if (c[index - 1] && Number(item) - Number(c[index - 1]) > 1) {
                    let e = []
                    if (c[index - 1].indexOf('-') > -1) {
                        for (let x = Number(c[index - 1].split('-')[1]) + 1; x < Number(item) - 1; x++) {
                            e.push(x)
                        }
                    } else {
                        for (let x = Number(c[index - 1]) + 1; x <= Number(item) - 1; x++) {
                            e.push(x)
                        }
                    }
                    d.push(e)

                }

            }

            d.push([Number(item)])

        }
    }
    )
    return d;

}




function tgbTo(hex) {

    let rgb = ''
    hex = hex.replace('#', '')
    for (let i = 0; i < hex.length; i += 2) {
        rgb += parseInt(hex.slice(i, i + 2), 16) + (i < 4 ? ',' : '')
    }
    rgb += ''
    return rgb


}
/**
 * 加载 pdf js 库的 pdf文档
 * @param pdfJsApp
 * @returns {Promise<PDFDocument>}
 */
async function loadPdfJsDoc(pdfJsApp) {
    const pageNum = pdfJsApp.pdfDocument.numPages
    const result = await pdfJsApp.pdfDocument.getData()

    // pdfJsApp.pdfDocument.getData().then(res => {
    //     console.log(new Uint8Array(res), 22222)
    // })
    // const data = await pdfJsApp.pdfDocument.saveDocument()


    return await PDFDocument.load(new Uint8Array(result.buffer))
    // return await PDFDocument.load(data)

}

/**
 * 加载pdf文件
 * @param file
 * @returns {Promise<unknown>}
 */
function loadPdfFile(file) {
    return new Promise(function (resolve, reject) {
        let reader = new FileReader();
        reader.onload = function (progressEvent) {
            resolve(reader.result);
        }
        reader.onerror = function (error) {
            reject(error);
        }
        reader.readAsArrayBuffer(file);
    });
}


/**
 * 基于pdf-lib的pdf编辑工具
 * @type {{merge(*): Promise<void>, insert(*, *, *): Promise<*>, remove(*, *): Promise<*>, rebuildPageNum(*, *): Promise<void>}}
 */
const PDFLibEditor = {


    /**
     * 保存PDF
     */
    // savePdf(pdfJsApp){
    //     var opt = {
    //         margin: 0.3,
    //         filename: "name.pdf",
    //         image: { type: "jpeg", quality: 1 },
    //         html2canvas: { scale: 2 },
    //         jsPDF: { unit: "in", format: "letter", orientation: "portrait" },
    //     };

    //     html2pdf().set(opt).from(pdfJsApp).save()
    // },


    
    /**
     * 旋转pdf
     */
    async degreesPdf(pdfJsApp,nums){
        let pdfDoc = await loadPdfJsDoc(pdfJsApp)
        const pageCount = pdfDoc.getPageCount()
        for (let i = 0; i < pageCount; i++) {
            
            const page = pdfDoc.getPage(i)
            page.setRotation(degrees(nums*90));
            
        }
        
        await pdfJsApp.open({ data: await pdfDoc.save() })
        

    },

    /**
     * 画横线
     * @param pdfJsApp
     * @param color 
     * @param size
     * @param start
     * @param end
     * 
     */

    async drawLine(pdfJsApp, color = "#000000", size = 1, start, end, IEwidth, IEheight) {
        const startX = start.x
        const startY = start.y
        const endX = end.x
        const endY = end.y
        let pdfDoc = await loadPdfJsDoc(pdfJsApp)
        const page = pdfDoc.getPage(pdfJsApp.page - 1)
        let rgbs = tgbTo(color)
        console.log({ x: startX / (992 / 595.32), y: page.getHeight() - startY / (992 / 595.32) },
            { x: endX / (992 / 595.32), y: page.getHeight() - startY / (992 / 595.32) },
            "开始坐标与结束坐标",
            page.getWidth(),
            page.getHeight(),
            IEwidth,
            IEheight,
        )
        // 992 / 595.32
        page.drawLine({
            start: { x: startX / (IEwidth / page.getWidth()), y: page.getHeight() - startY / (IEheight / page.getHeight()) },
            end: { x: endX / (IEwidth / page.getWidth()), y: page.getHeight() - startY / (IEheight / page.getHeight()) },
            color: rgb(Number(rgbs.split(",")[0]) / 255, Number(rgbs.split(",")[1]) / 255, Number(rgbs.split(",")[2]) / 255),
            thickness: size,
        });
        await pdfJsApp.open({ data: await pdfDoc.save() })

    },



    /**
     * 重新生成页码
     * @param pdfJsApp
     * @param position 1- 左上,2-上中,3-右上,4-左下,5-下中,6-右下
     * @returns {Promise<void>}
     */
    async rebuildPageNum(pdfJsApp, position, startPageNum, mergeAdd = false) {
        if (!pdfJsApp) {
            console.error("pdf js application:", pdfJsApp)
            return
        }
        // if (!position) {
        //     position = 3
        // }
        let pdfDoc
        if (mergeAdd) {
            pdfDoc = pdfJsApp
        } else {
            pdfDoc = await loadPdfJsDoc(pdfJsApp)
        }

        const pageCount = pdfDoc.getPageCount()
        for (let i = 0; i < pageCount; i++) {
            const num = Number(startPageNum) + i + ''
            const page = pdfDoc.getPage(i)
            page.drawText(num, {
                ...computePosition(position, page.getWidth(), page.getHeight(), num.length),
                size: 12
            })
        }
        if (mergeAdd) {
            return pdfDoc

        } else {
            await pdfJsApp.open({ data: await pdfDoc.save() })
        }


    },
    /**
     * 合并pdf
     * @param pdfJsApp pdfjs application
     * @param pdfFiles
     * @param path
     * @param isAppend
     * @returns {Promise<void>}
     */
    async mergePages(pdfJsApp, pdfFiles, path, mergeAdd, radio2, startPageNum) {
        if (!pdfJsApp) {
            console.error("pdf js application:", pdfJsApp)
            return
        }
        if (!pdfFiles) {
            console.error("merge pdf file:", pdfFiles)
            return
        }
        let pdfDoc;
        // if (isAppend) {
        //     pdfDoc = loadPdfJsDoc(pdfJsApp)
        // } else {
        pdfDoc = await PDFDocument.create()
        // }

        for (let i = 0; i < pdfFiles.length; i++) {
            const data = await loadPdfFile(pdfFiles[i].raw)
            const mergeDoc = await PDFDocument.load(new Uint8Array(data))
            const mergePageCount = Array.from(new Array(mergeDoc.getPageCount()).keys())
            const copiedPages = await pdfDoc.copyPages(mergeDoc, mergePageCount)
            for (let i = 0; i < copiedPages.length; i++) {
                await pdfDoc.addPage(copiedPages[i])
            }
        }
        if (mergeAdd) {
            const page = await this.rebuildPageNum(pdfDoc, radio2, startPageNum, true)
            window.ipcRenderer.send('saveFile', { FileList: [await page.save()], path: path })
        } else {
            window.ipcRenderer.send('saveFile', { FileList: [await pdfDoc.save()], path: path })

        }

        // window.ipcRenderer.send('saveFile', { FileList: [await pdfDoc.save()], path: path })



    },
    /**
     * 在指定位置之后插入pdf page
     * @param pdfJsApp pdfjs application
     * @param insertPdfFile
     * @param pageNum
     * @returns {Promise<*>}
     */
    async insertPages(pdfJsApp, insertPdfFile, pageNum) {


        if (!pdfJsApp) {
            console.error("pdf js application:", pdfJsApp)
            return
        }
        if (!insertPdfFile) {
            console.error("insert pdf file:", insertPdfFile)
            return
        }
        // if (!pageNum) {
        //     console.error("insert pdf pageNum:", pageNum)
        //     return
        // }
        // const render = new FileReader()
        // render.readAsArrayBuffer(insertPdfFile)
        // render.onload = async function () {
        const pdfDoc = await loadPdfJsDoc(pdfJsApp)

        const insertDoc = await PDFDocument.load(insertPdfFile)

        const insertPageCount = Array.from(new Array(insertDoc.getPageCount()).keys())

        const copiedPages = await pdfDoc.copyPages(insertDoc, insertPageCount)
        for (let i = copiedPages.length - 1; i >= 0; i--) {
            await pdfDoc.insertPage(pageNum, copiedPages[i])
        }

        //     const mergedPdfBytes = await pdfDoc.save();
        // var downloadLink = document.createElement('a');
        // downloadLink.href = URL.createObjectURL(new Blob([mergedPdfBytes]));
        // downloadLink.download = 'merged_pdf.pdf';
        // document.body.appendChild(downloadLink);
        // downloadLink.click();
        // document.body.removeChild(downloadLink);
        await pdfJsApp.open({ data: await pdfDoc.save() })
        // }
    }
    ,
    /**
     * 删除指定的pdf页面
     * @param pdfJsApp pdfjs application
     * @param pagesStr
     * @returns {Promise<*>}
     */
    async removePages(pdfJsApp, pagesStr) {
        if (!pdfJsApp) {
            console.error("pdf js application:", pdfJsApp)
            return
        }
        
        const pdfDoc = await loadPdfJsDoc(pdfJsApp)
        getPages(pagesStr).forEach(num => {
            pdfDoc.removePage(num - 1)
        })
        const data = await pdfDoc.save()
        await pdfJsApp.open({ data: data })
    }
    ,

    // 拆分pdf
    async splitPages(pdfJsApp, pagesStr, pageNum, path) {
        let list = splitList(pagesStr, pageNum)
        const pastPdfDoc = await loadPdfJsDoc(pdfJsApp)

        let FileList = []
        for (let z = 0; z < list.length; z++) {

            let pdfDoc = await PDFDocument.create()

            let list_1 = []
            for (let y = 0; y < list[z].length; y++) {
                list_1.push(list[z][y] - 1)
            }
            console.log(list, "zzzzzzzz")
            let copiedPages = await pdfDoc.copyPages(pastPdfDoc, list_1)

            for (let i = 0; i < copiedPages.length; i++) {
                await pdfDoc.addPage(copiedPages[i])

            }
            FileList.push(await pdfDoc.save())
            // window.ipcRenderer.send('saveFile', { FileList: [await pdfDoc.save()], path: path })



        }
        window.ipcRenderer.send('saveFile', { FileList: FileList, path: path })


    }




}

export {
    PDFLibEditor
}

在vue中文件使用,以删除pdf为例:

 // 删除pdf
    async removePdfPages(){
      if(this.pageSize1.indexOf(",")>-1){
        window.$messageInfo.warning('请使用英文逗号!')
        return
      } 
      const pdfApp = this.$refs.iframe.contentWindow.PDFViewerApplication
      await PDFLibEditor.removePages(pdfApp, this.radio3==1?String(pdfApp.page):this.pageSize1)
      this.dialogVisible2 = false
      this.pageSize1 = ''
      this.radio3 = '1'
    },
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我来回答你的问题。 1. Java将HTML转化为PDF 你可以使用开源的工具,比如 iText、Flying Saucer、PDFBox 等来实现将 HTML 转化为 PDF功能。其中,iText 是比较常用的一个工具,你可以通过以下代码实现将 HTML 转化为 PDF: ```java import com.itextpdf.html2pdf.HtmlConverter; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class HtmlToPdf { public static void main(String[] args) throws IOException { FileInputStream htmlFile = new FileInputStream("input.html"); FileOutputStream pdfFile = new FileOutputStream("output.pdf"); HtmlConverter.convertToPdf(htmlFile, pdfFile); } } ``` 2. 获得页数 使用 iText 工具,你可以通过以下代码获得 PDF 文件的页数: ```java import com.itextpdf.text.pdf.PdfReader; public class GetPageCount { public static void main(String[] args) throws IOException { PdfReader pdfReader = new PdfReader("input.pdf"); int pageCount = pdfReader.getNumberOfPages(); System.out.println("Page count: " + pageCount); pdfReader.close(); } } ``` 3. 合并PDF 使用 iText 工具,你可以通过以下代码实现合并多个 PDF 文件: ```java import com.itextpdf.text.Document; import com.itextpdf.text.pdf.PdfCopy; import com.itextpdf.text.pdf.PdfReader; import java.io.FileOutputStream; import java.io.IOException; public class MergePdf { public static void main(String[] args) throws IOException { Document document = new Document(); PdfCopy copy = new PdfCopy(document, new FileOutputStream("output.pdf")); document.open(); PdfReader reader1 = new PdfReader("input1.pdf"); PdfReader reader2 = new PdfReader("input2.pdf"); copy.addDocument(reader1); copy.addDocument(reader2); document.close(); reader1.close(); reader2.close(); } } ``` 希望这些代码能对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值