PDFを操作するプログラム(ページ数の多いPDFファイルに目次を作って目的のページを瞬時に開く)

何十ページ、何百ページとあるPDFファイルに目次を作るためのプログラムです。
PDFと同じ名前のテキストファイルを用意して、以下の様な目次を書き込めばOK。

13,第2章
42,第3章

左側がページ番号、右側が目次タイトルです。

Acrobat SDKを使う場合と使わない場合の二つのC#コードを書きました。

Acrobat SDKを使わない方法

using System;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        MainMenu mainmenu = new MainMenu();
        MenuItem top = new MenuItem();
        string select_filename;
        readonly string[] _kugiri = { ".pdf", ".PDF" };
        readonly string[] _dot = { "," };

        private void Form1_Load(object sender, EventArgs e)
        {
            MenuItem file_choose = new MenuItem();
            file_choose.Text = "PDFファイル選択";
            file_choose.Click += new EventHandler(file_choose_Click);
            mainmenu.MenuItems.Add(file_choose);
            top.Text = "目次";
            mainmenu.MenuItems.Add(top);
            this.Menu = mainmenu;
        }

        private void file_choose_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.InitialDirectory = Environment.CurrentDirectory;
            ofd.Filter = "PDFファイル|*.pdf;*.PDF";
            if (ofd.ShowDialog(this) == DialogResult.OK)
            {
                top.MenuItems.Clear();
                String folder = System.IO.Path.GetDirectoryName(ofd.FileName);
                String filename = System.IO.Path.GetFileName(ofd.FileName);
                select_filename = ofd.FileName;
                string[] filename2 = filename.Split(_kugiri, StringSplitOptions.RemoveEmptyEntries);
                webBrowser1.Navigate(select_filename);

                //同名のテキストファイルを探す
                if (System.IO.File.Exists(folder + "/" + filename2[0] + ".txt"))
                {
                    MenuItem[] mokuzi;
                    //内容を一行ずつ読み込む
                    string[] lines = System.IO.File.ReadAllLines(folder + "/" + filename2[0] + ".txt", System.Text.Encoding.GetEncoding("UTF-8"));
                    //空白を削除 
                    string[] lines2 = Array.FindAll(lines, line => line != "");
                    mokuzi = new MenuItem[lines2.Length];
                    string[] page = new string[lines2.Length];
                    string[] title = new string[lines2.Length];
                    for (int i = 0; i < lines2.Length; i++)
                    {
                        page[i] = lines2[i].Split(_dot, StringSplitOptions.RemoveEmptyEntries)[0];
                        title[i] = lines2[i].Split(_dot, StringSplitOptions.RemoveEmptyEntries)[1];
                        mokuzi[i] = new MenuItem(); mokuzi[i].Text = title[i];
                        mokuzi[i].Name = page[i];
                        top.MenuItems.Add(mokuzi[i]);
                        mokuzi[i].Click += new EventHandler(mokuzi_Click);
                    }
                }
            }
        }
        private void mokuzi_Click(object sender, EventArgs e)
        {
            int currentpage = int.Parse(((MenuItem)sender).Name);
            webBrowser1.Navigate(select_filename + "#page=" + currentpage.ToString());
            //次の1文がないとうまくいかない(キャッシュのクリア?)
            MessageBox.Show("jump to page" + currentpage.ToString());
            webBrowser1.Refresh();
        }
    }
}

Acrobat SDKを使う方法

using System;
using System.Windows.Forms;

namespace PDF
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        MainMenu main = new MainMenu();
        MenuItem top = new MenuItem();
        readonly string[] _kugiri = { ".pdf", ".PDF" };
        readonly string[] _dot = { "," };

        private void Form1_Load(object sender, EventArgs e)
        {
            MenuItem file_choose = new MenuItem();
            file_choose.Text = "PDFファイル選択";
            file_choose.Click += new EventHandler(file_choose_Click);
            main.MenuItems.Add(file_choose);
            top.Text = "目次";
            main.MenuItems.Add(top);
            this.Menu = main; 
        }
        private void file_choose_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.InitialDirectory = Environment.CurrentDirectory;
            ofd.Filter = "PDFファイル|*.pdf;*.PDF"; 
            if (ofd.ShowDialog(this) == DialogResult.OK)
            {
                top.MenuItems.Clear();
                String folder = System.IO.Path.GetDirectoryName(ofd.FileName);
                String filename = System.IO.Path.GetFileName(ofd.FileName);
                string[] filename2 = filename.Split(_kugiri, StringSplitOptions.RemoveEmptyEntries);
                axAcroPDF1.LoadFile(ofd.FileName);
                //同名のテキストファイルを探す
                if (System.IO.File.Exists(folder + "/" + filename2[0] + ".txt"))
                {
                    MenuItem[] mokuzi;
                    //内容を一行ずつ読み込む
                    string[] lines = System.IO.File.ReadAllLines(folder + "/" + filename2[0] + ".txt", System.Text.Encoding.GetEncoding("shift_jis"));
                    //空白を削除 
                    string[] lines2 = Array.FindAll(lines, line => line != ""); 
                    mokuzi = new MenuItem[lines2.Length];
                    string[] page = new string[lines2.Length];
                    string[] title = new string[lines2.Length];
                    for (int i = 0; i < lines2.Length; i++)
                    {
                        page[i] = lines2[i].Split(_dot, StringSplitOptions.RemoveEmptyEntries)[0];
                        title[i] = lines2[i].Split(_dot, StringSplitOptions.RemoveEmptyEntries)[1];
                        mokuzi[i] = new MenuItem(); mokuzi[i].Text = title[i];
                        mokuzi[i].Name = page[i];
                        top.MenuItems.Add(mokuzi[i]);
                        mokuzi[i].Click += new EventHandler(mokuzi_Click);
                    }
                }
            }
        }
        private void mokuzi_Click(object sender, EventArgs e)
        {
            int currentpage = int.Parse(((MenuItem)sender).Name);
            axAcroPDF1.setCurrentPage(currentpage);
        }
    }
}

2022年5月6日追記(コードの改訂)

touch-sp.hatenablog.com