diff --git a/.gitignore b/.gitignore index 6704566..3bf5fb7 100644 --- a/.gitignore +++ b/.gitignore @@ -102,3 +102,6 @@ dist # TernJS port file .tern-port +build +dist +__pycache__ \ No newline at end of file diff --git a/A4.pdf b/A4.pdf new file mode 100644 index 0000000..7f3ac5c Binary files /dev/null and b/A4.pdf differ diff --git a/Readme.txt b/Readme.txt new file mode 100644 index 0000000..ce35bb5 --- /dev/null +++ b/Readme.txt @@ -0,0 +1,31 @@ +@author JMx +date 2018-04-26 +pdf文件拆分,合并,剪切等功能. + + 1 将pdf文件拆分成单页. + split_pdf_each(infn): + "infn"表示文件名(含路径). + 例:split_pdf_each('F:/pdf/test.pdf'). + + 2 将pdf文件拆分成多个部分. + split_pdf_parts(infn, parts): + "infn"为文件名(含路径). + "parts"为每个部分起始页码列表. + 例:split_pdf_parts('F:/p/1.pdf',[(1,3),(40,50)]). + + 3 将多个pdf文件合并成一个. + merge_pdf(infnList, outfn): + "infnList"为要合并的文件名(含路径)列表. + "outfn"为合并后文件名(含路径). + 例:merge_pdf(['F:/1.pdf','F:/2.pdf'], 'F:/12.pdf'). + + 4 将pdf文件页面剪切至合适大小. + cut_pdf(infn, left, right, lower, upper, option, isTest): + "infn"表示文件名(含路径). + 2~5四个参数分别是四周需要剪去的宽度(一般在10~160). + "option"为剪切方式,all/odd/even 页. + "isTest"表示是否先对第一页进行测试. + 例:cut_pdf('F:/1.pdf',20,20,20,20,'even',1).测试. + 只剪切前两页,单独生成一个pdf文件. + cut_pdf('F:/1.pdf',20,20,20,20,'odd',0)不测试. + 剪切奇数页. \ No newline at end of file diff --git a/page-number.pdf b/page-number.pdf new file mode 100644 index 0000000..81e2bd6 Binary files /dev/null and b/page-number.pdf differ diff --git a/pdf-page-size-2-a4.py b/pdf-page-size-2-a4.py new file mode 100644 index 0000000..d5d383c --- /dev/null +++ b/pdf-page-size-2-a4.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# @Author: old jia +# @Email: jiaminxin@outlook.com +# @Date: 2019-08-22 13:25:39 +# @Last Modified by: old jia +# @Last Modified time: 2019-08-23 23:04:33 +import sys +from pdfrw import PdfReader, PdfWriter, PageMerge, IndirectPdfDict + +def get_size(infn, i): + pdf = PdfReader(infn) + size = PageMerge().add(pdf.pages[i]).xobj_box; + print(size) + return (size[2], size[3]) + +def get_scale_margin(infn, a4_size, i): + size = get_size(infn, i) + width_ratio = a4_size[0] / size[0] + height_ratio = a4_size[1] / size[1] + scale = max(width_ratio, height_ratio) + if width_ratio > height_ratio : + margin = (size[1] * scale - a4_size[1]) / 2 + is_vertical = 1 + else: + margin = (size[0] * scale- a4_size[0]) / 2 + is_vertical = 0 + return (scale, margin, is_vertical) + +def adjust(page, params): + scale, margin, is_vertical = params + info = PageMerge().add(page) + x1, y1, x2, y2 = info.xobj_box + if is_vertical == 1: + viewrect = (0, margin / scale, x2, y2 - 2 * margin / scale) + else: + viewrect = (margin / scale, 0, x2 - 2 * margin / scale, y2) + page = PageMerge().add(page, viewrect=viewrect) + page[0].scale(scale) + return page.render() + +def resize_2_a4(infn): + outfn = infn[:-4] + '-A4.pdf'; + reader = PdfReader(infn) + writer = PdfWriter(outfn) + a4_size = get_size('A4.pdf', 0) + params = get_scale_margin(infn, a4_size, 0) + for page in reader.pages: + writer.addpage(adjust(page, params)) + writer.trailer.Info = IndirectPdfDict(reader.Info or {}) + writer.write() + +if __name__ == '__main__': + cmd = sys.argv[1].encode('gb2312').decode('gb2312'); + resize_2_a4(cmd); \ No newline at end of file diff --git a/pdf-zoom.py b/pdf-zoom.py new file mode 100644 index 0000000..6d8be73 --- /dev/null +++ b/pdf-zoom.py @@ -0,0 +1,22 @@ +import sys +import os + +from pdfrw import PdfReader, PdfWriter, PageMerge, IndirectPdfDict + + +def adjust(page, margin=0, scale=1): + info = PageMerge().add(page) + x1, y1, x2, y2 = info.xobj_box + viewrect = (margin, margin, x2 - x1 - 2 * margin, y2 - y1 - 2 * margin) + page = PageMerge().add(page, viewrect=viewrect) + page[0].scale(scale) + return page.render() + + +inpfn = 'F:page-number.pdf' +outfn = 'F:poster.' + os.path.basename(inpfn) +reader = PdfReader(inpfn) +writer = PdfWriter(outfn) +writer.addpage(adjust(reader.pages[0])) +writer.trailer.Info = IndirectPdfDict(reader.Info or {}) +writer.write() \ No newline at end of file diff --git a/pdf.py b/pdf.py new file mode 100644 index 0000000..d29ce72 --- /dev/null +++ b/pdf.py @@ -0,0 +1,96 @@ +import wx, time +from pdfdo import PDF +from threading import Thread + +# Next, create an application object. +app = wx.App() + +# Then a frame. +frm = wx.Frame(None, title="pdf处理器", pos = (500, 300), size = (500, 350)); + +fn = '' +path = '' +def select_files(): + if fileDialog.ShowModal() == wx.ID_OK: + global fn, path + path = fileDialog.GetDirectory() + fn = [path + '\\' + f for f in fileDialog.GetFilenames()] + wx.FindWindowById(0).SetValue(str(fn)) + pdfdo.infn = fn + message.SetValue(str(pdfdo.pdf_info())) + +# component + +def btn_callback(event): + id_ = event.GetId() + + if id_ == 1: + select_files() + return + + if fn == '': + return + + pdfdo.message = '' + param_ = wx.FindWindowById(id_ - 1).GetValue() + param = [] + if (id_ != 3) & (id_ != 7) & (id_ != 13): + try: + param = eval(param_) + except: + message.SetValue('输入格式有误') + return + + Thread(target = update_state).start() + + pdfdo.params = param; + + if id_ == 3: + Thread(target = pdfdo.split_pdf_each).start() + elif id_ == 5: + Thread(target = pdfdo.split_pdf_parts).start() + elif id_ == 7: + pdfdo.params = path + '\\' + param_ + Thread(target = pdfdo.merge_pdf).start() + elif id_ == 9: + Thread(target = pdfdo.cut_pdf).start() + elif id_ == 11: + Thread(target = pdfdo.rotate_pdf).start() + elif id_ == 13: + Thread(target = pdfdo.add_watermark).start() + + +def update_state(): + message.SetValue(pdfdo.message) + if ('完成' not in pdfdo.message) & ('出错了' not in pdfdo.message): + time.sleep(1) + update_state() + else: + message.SetValue(pdfdo.message) + +# select file +fileDialog = wx.FileDialog(frm, message = '选择文件', wildcard = '*.pdf', style = wx.FD_OPEN | wx.FD_MULTIPLE, pos = (200, 30), size = (100, 25)) + +# input/button: pos = (left, top), size = (width, height). +# varibles. +left = 15; +width = 390; +top = 20; +margin = 36; +labels = ['选择文件', '拆分每页', '部分拆分', '文件合并', '文件剪切', '文件旋转', '添加页码']; +default_values = ['', '支持单个文件', '支持单个文件, 如:[(1, 3), (20, 25), (30, 40)]', '合并后文件名.pdf', '支持单个文件,如:[10, 20, 10, 20, "even", 1] (注:左, 右, 下, 上, odd/even/all, 0/1: 0为全部, 1为测试10张)', '支持单个文件,如:[90, 1] (注:旋转度数是90的整数倍, 0/1: 1为测试一张, 0为全部)', '支持多个文件'] +length = len(labels) + +for i in range(length): + wx.TextCtrl(frm, id = 2 * i, value = default_values[i], pos = (left, top + margin * i), size = (width, 25)); + wx.Button(frm, id = 2 * i + 1, label = labels[i], pos = (width + 20, top + margin * i), size = (60, 25)).Bind(wx.EVT_BUTTON, btn_callback); + +message = wx.TextCtrl(frm, value = "状态框", pos = (left, top + margin * length + 5), size = (455, 25)) + +pdfdo = PDF() + +# Show it. +frm.Show() + +# Start the event loop. +app.MainLoop() \ No newline at end of file diff --git a/pdf.spec b/pdf.spec new file mode 100644 index 0000000..0ba9f47 --- /dev/null +++ b/pdf.spec @@ -0,0 +1,32 @@ +# -*- mode: python -*- + +block_cipher = None + + +a = Analysis(['pdf.py'], + pathex=['D:\\nodejs\\myproject\\pdfdo'], + binaries=[], + datas=[], + hiddenimports=[], + hookspath=[], + runtime_hooks=[], + excludes=[], + win_no_prefer_redirects=False, + win_private_assemblies=False, + cipher=block_cipher, + noarchive=False) +pyz = PYZ(a.pure, a.zipped_data, + cipher=block_cipher) +exe = EXE(pyz, + a.scripts, + a.binaries, + a.zipfiles, + a.datas, + [], + name='pdf', + debug=False, + bootloader_ignore_signals=False, + strip=False, + upx=True, + runtime_tmpdir=None, + console=False ) diff --git a/pdfdo.py b/pdfdo.py new file mode 100644 index 0000000..22b7358 --- /dev/null +++ b/pdfdo.py @@ -0,0 +1,116 @@ +from PyPDF2 import PdfFileReader, PdfFileWriter +import sys + +class PDF: + def __init__(self): + self.infn = [] + self.params = '' + self.message = '' + + def pdf_info(self): + return [ 'ID:%d, 页数:%d, 宽×高:%d×%d ' % (i+1, p.getNumPages(), p.getPage(0).mediaBox.upperRight[0], p.getPage(0).mediaBox.upperRight[1]) for i, p in enumerate( [ PdfFileReader( open(p, 'rb') ) for p in self.infn ] ) ] + + + def split_pdf_each(self): + try: + pdf_input = PdfFileReader(open(self.infn[0], 'rb')) + pages = pdf_input.getNumPages() + self.message = '正在拆分...' + for i in range(pages): + pdf_output = PdfFileWriter() + pdf_output.addPage(pdf_input.getPage(i)) + pdf_output.write(open(self.infn[0][:-4] + '-' + str(i + 1) + '.pdf', 'wb')) + self.message = '已拆分%.2f' %((i + 1)/pages * 100) + '%' + self.message = '拆分完成' + except: + self.message = '出错了,请检查输入格式是否正确' + + def split_pdf_parts(self): + try: + pdf_input = PdfFileReader(open(self.infn[0], 'rb')) + self.message = '正在拆分...' + for part in self.params: + pdf_output = PdfFileWriter() + for i in range(part[0] - 1, part[1]): + pdf_output.addPage(pdf_input.getPage(i)); + pdf_output.write(open(self.infn[0][:-4] + '-' + str(part[0]) + '-' + str(part[1]) + '.pdf', 'wb')) + self.message = '第%d部分已拆分'%(self.params.index(part) + 1) + self.message = '拆分完成' + except: + self.message = '出错了,请检查输入格式是否正确' + + def merge_pdf(self): + try: + pdf_output = PdfFileWriter() + self.message = '正在合并...' + for infn in self.infn: + self.message = infn + pdf_input = PdfFileReader(open(infn, 'rb')) + pages = pdf_input.getNumPages() + for i in range(pages): + self.message = str(i) + '/' + str(pages) + ': ' + infn + pdf_output.addPage(pdf_input.getPage(i)) + pdf_output.write(open(self.params, 'wb')) + self.message = '合并完成' + except: + self.message = '出错了,请检查输入格式是否正确' + + def cut_pdf(self): + try: + left, right, lower, upper, option, isTest = self.params; + self.message = '正在剪切' + pdf_input = PdfFileReader(open(self.infn[0], 'rb')); + pdf_output = PdfFileWriter(); + pages = pdf_input.getNumPages() + if isTest == 1: + pages = min(10 * isTest, pages) + for i in range(pages): + page = pdf_input.getPage(i); + if (option == 'all') or (option == 'odd' and i%2 == 0) or (option == 'even' and (i+1)%2 == 0): + page.mediaBox.upperLeft = (left, page.mediaBox.upperLeft[1] - upper) + page.mediaBox.upperRight = (page.mediaBox.upperRight[0] - right, page.mediaBox.upperRight[1] - upper) + page.mediaBox.lowerLeft = (left, lower) + page.mediaBox.lowerRight = (page.mediaBox.lowerRight[0] - right, lower) + pdf_output.addPage(page); + self.message = str(i) + '/' + str(pages) + pdf_output.write(open(self.infn[0][:-4] + '-cut.pdf', 'wb')); + self.message = '剪切完成' + except: + self.message = '出错了,请检查输入格式是否正确' + + def rotate_pdf(self): + try: + rotation, isTest = self.params + self.message = '正在旋转' + pdf_input = PdfFileReader(open(self.infn[0], 'rb')); + pdf_output = PdfFileWriter(); + pages = isTest or pdf_input.getNumPages(); + for i in range(pages): + page = pdf_input.getPage(i); + page.rotateClockwise(rotation); + pdf_output.addPage(page); + self.message = str(i) + '/' + str(pages) + pdf_output.write(open(self.infn[0][:-4] + '-rotate.pdf', 'wb')); + self.message = '完成旋转' + except: + self.message = '出错了,请检查输入格式是否正确(旋转角度为90的倍数)' + + def add_watermark(self): + try: + self.message = '正在添加页码' + water_pdf = PdfFileReader(open('page-number.pdf', 'rb')); + water_pages = water_pdf.getNumPages() + for infn in self.infn: + pdf_input = PdfFileReader(open(infn, 'rb')); + pages = min(pdf_input.getNumPages(), water_pages); + pdf_output = PdfFileWriter(); + for i in range(pages): + page = pdf_input.getPage(i); + water_page = water_pdf.getPage(i); + page.mergePage(water_page); + pdf_output.addPage(page); + self.message = str(i) + '/' + str(pages) + ': ' + infn + pdf_output.write(open(infn[:-4] + '-number2.pdf', 'wb')); + self.message = '页码添加完成' + except: + self.message = '出错了,请检查输入格式是否正确(page-number.pdf文件要求和程序在同一目录)' \ No newline at end of file diff --git a/pyinstaller.txt b/pyinstaller.txt new file mode 100644 index 0000000..d8d3514 --- /dev/null +++ b/pyinstaller.txt @@ -0,0 +1,4 @@ +cd D: +D: +cd nodejs/myproject/pdfdo +pyinstaller -F -w pdf.py \ No newline at end of file diff --git a/server.py b/server.py new file mode 100644 index 0000000..f6bbf69 --- /dev/null +++ b/server.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# @Author: old jia +# @Email: jiaminxin@outlook.com +# @Date: 2019-06-26 19:39:18 +# @Last Modified by: old jia +# @Last Modified time: 2019-06-26 19:45:57 + +import http.server +import os + +PORT = 8080 + +def callback(a, b, c): + os.system('chrome localhost') + print(1) + +if __name__ == "__main__": + try: + server = http.server.HTTPServer(("", PORT), callback) + print("HTTP server is starting at port "+repr(PORT)+'...') + print("Press ^C to quit") + server.serve_forever() + except KeyboardInterrupt: + print("^Shutting down server...") + server.socket.close()