アイコン 株式会社トラスト・ソフトウェア・システム
電話:03-5316-3375info@trustss.co.jp
電話:03-5316-3375info@trustss.co.jp

開発者向けPDFライブラリ - Pdftools SDK(Toolbox add-on)

PDFを新規に生成

PDF生成機能

各種の開発言語(C/C++、.Net、Java、Pythonなど)を使用して新たにPDFファイルを作成できます。
PDFファイルを作成した後、Toolbox Add-onを使用してコンテンツの追加フォーム フィールドの追加メタデータの管理などができます。

 INFO:
この機能はToolbox add-onの機能ですが、「Pdftools SDK」ライブラリ用のライセンスキーで機能します。
Toolbox add-onの全機能は無償で試用できますが、試用版のライセンスキーが必要です。
試用ライセンスキー要求からご要望ください。

Pdftools SDK 価格見積もり

APIリファレンス (Toolbox Add-on)

Toolbox Add-onのAPIリファレンスはこちらです。(すべて英文)

サンプル

C#のサンプルプロジェクトではPdftools SDK(Toolbox Add-on)ライブラリ(DLL)をNuGetから自動でダウンロードします。
CのサンプルプロジェクトにはPdftools SDK(Toolbox Add-on)ライブラリ(DLL)が含まれています。

 
Toolbox add-onの全機能は無償で試用できますが、試用版(無料)のライセンスキーが必要です。
試用ライセンスキー要求からご要望ください。

License Agreement(利用許諾契約書)が含まれていますので必ず確認してください。


新たなPDF文書の作成

新たなPDFを作成し、文字列を追加

全1ページの新しいPDFドキュメントを作成し、このページの指定された矩形領域内に両端揃えレイアウトのテキストブロックを追加します。


サンプル・プロジェクト(C#)をダウンロード
サンプル・プロジェクト(Python)をダウンロード
サンプル・プロジェクトをダウンロード
サンプル・プロジェクトの実行手順を参照してください
// Create output document
using (Stream outStream = new FileStream(outPath, FileMode.CreateNew, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, null, null))
{
    Font font = Font.CreateFromSystem(outDoc, "Arial", "Italic", true);

    // Create page
    Page outPage = Page.Create(outDoc, PageSize);

    // Add text as justified text
    LayoutText(outDoc, outPage, textPath, font, 20);

    // Add page to document
    outDoc.Pages.Add(outPage);
}
private static void LayoutText(Document outputDoc, Page outPage, string textPath, Font font,
    double fontSize)
{
    // Create content generator 
    using ContentGenerator gen = new ContentGenerator(outPage.Content, false);

    // Create text object
    Text text = Text.Create(outputDoc);

    // Create text generator
    using TextGenerator textGenerator = new TextGenerator(text, font, fontSize, null);

    // Calculate position
    Point position = new Point
    {
        X = Border,
        Y = outPage.Size.Height - Border
    };

    // Move to position
    textGenerator.MoveTo(position);

    // Loop through all lines of the textinput
    string[] lines = File.ReadAllLines(textPath, Encoding.Default);
    foreach (string line in lines)
    {
        // Split string in substrings
        string[] substrings = line.Split(new char[] { ' ' }, StringSplitOptions.None);
        string currentLine = null;
        double maxWidth = outPage.Size.Width - Border * 2;
        int wordcount = 0;

        // Loop through all words of input strings
        foreach (string word in substrings)
        {
            string tempLine;

            // Concatenate substrings to line
            if (currentLine != null)
                tempLine = currentLine + " " + word;
            else
                tempLine = word;

            // Calculate the current width of line
            double width = textGenerator.GetWidth(currentLine);
            if (textGenerator.GetWidth(tempLine) > maxWidth)
            {
                // Calculate the word spacing
                textGenerator.WordSpacing = (maxWidth - width) / (wordcount - 1);
                // Paint on new line
                textGenerator.ShowLine(currentLine);
                textGenerator.WordSpacing = 0;
                currentLine = word;
                wordcount = 1;
            }
            else
            {
                currentLine = tempLine;
                wordcount++;
            }
        }
        textGenerator.WordSpacing = 0;
        // Add given stamp string
        textGenerator.ShowLine(currentLine);
    }
    // Paint the positioned text
    gen.PaintText(text);
}
サンプル・プロジェクトの実行手順を参照してください
def layout_text(output_doc: Document, out_page: Page, text_path: str, font: Font, font_size: float):
    """
    Layout and justify text on the PDF page.
    """
    # Create content generator
    with ContentGenerator(out_page.content, False) as generator:

        # Create text object
        text = Text.create(output_doc)

        # Create text generator
        with TextGenerator(text, font, font_size, None) as text_generator:

            # Calculate starting position
            position = Point(x=BORDER, y=out_page.size.height - BORDER)

            # Move to position
            text_generator.move_to(position)

            with open(text_path, "r", encoding="utf-8") as file:
                lines = file.readlines()

            # Loop through all lines of the textinput
            for line in lines:
                # Split string in substrings
                substrings = line.split(" ")
                current_line = ""
                max_width = out_page.size.width - BORDER * 2
                word_count = 0

                # Loop through all words of input strings
                for word in substrings:
                    # Concatenate substrings to line
                    temp_line = f"{current_line} {word}".strip()

                    # Calculate the current width of line
                    current_width = text_generator.get_width(current_line)

                    if text_generator.get_width(temp_line) > max_width:
                        # Calculate the word spacing
                        text_generator.word_spacing = (max_width - current_width) / (word_count - 1) if word_count > 1 else 0
                        text_generator.show_line(current_line)
                        text_generator.word_spacing = 0
                        current_line = word
                        word_count = 1
                    else:
                        current_line = temp_line
                        word_count += 1

                text_generator.word_spacing = 0
                # Add given stamp string
                text_generator.show_line(current_line)

        # Paint the positioned text
        generator.paint_text(text)
# Define global variables
BORDER = 50
PAGE_SIZE = Size(width=595, height=842)  # A4 page size in points

# Create output document
with io.FileIO(output_file_path, "wb+") as out_stream:
    with Document.create(out_stream, None, None) as out_doc:

        font = Font.create_from_system(out_doc, "Arial", "Italic", True)

        # Create page
        out_page = Page.create(out_doc, PAGE_SIZE)

        # Add text as justified text
        layout_text(out_doc, out_page, input_text_path, font, font_size=20)

        # Add page to document
        out_doc.pages.append(out_page)

小冊子になるPDFの作成

小冊子用のPDFを作成

A3サイズのページに最大で2枚のA4ページを正しい順序で配置したPDFを作成します。
このPDFをA3ページの両面印刷して、折りたたむと小冊子になります。


サンプル・プロジェクト(C)をダウンロード
サンプル・プロジェクト(C#)をダウンロード
サンプル・プロジェクト(Python)をダウンロード
サンプル・プロジェクトをダウンロード
サンプル・プロジェクトの実行手順を参照してください
int copyDocumentData(TPtxPdf_Document* pInDoc, TPtxPdf_Document* pOutDoc)
{
    // Objects that need releasing or closing
    TPtxPdfContent_IccBasedColorSpace* pInOutputIntent    = NULL;
    TPtxPdfContent_IccBasedColorSpace* pOutOutputIntent   = NULL;
    TPtxPdf_Metadata*                  pInMetadata        = NULL;
    TPtxPdf_Metadata*                  pOutMetadata       = NULL;
    TPtxPdfNav_ViewerSettings*         pInViewerSettings  = NULL;
    TPtxPdfNav_ViewerSettings*         pOutViewerSettings = NULL;
    TPtxPdf_FileReferenceList*         pInFileRefList     = NULL;
    TPtxPdf_FileReferenceList*         pOutFileRefList    = NULL;
    TPtxPdf_FileReference*             pInFileRef         = NULL;
    TPtxPdf_FileReference*             pOutFileRef        = NULL;

    iReturnValue = 0;

    // Output intent
    pInOutputIntent = PtxPdf_Document_GetOutputIntent(pInDoc);
    if (pInOutputIntent != NULL)
    {
        pOutOutputIntent = PtxPdfContent_IccBasedColorSpace_Copy(pOutDoc, pInOutputIntent);
        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutOutputIntent,
                                         _T("Failed to copy ICC-based color space. %s (ErrorCode: 0x%08x)\n"),
                                         szErrorBuff, Ptx_GetLastError());
        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Document_SetOutputIntent(pOutDoc, pOutOutputIntent),
                                          _T("Failed to set output intent. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
                                          Ptx_GetLastError());
    }
    else
        GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get output intent. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
                                          Ptx_GetLastError());

    // Metadata
    pInMetadata = PtxPdf_Document_GetMetadata(pInDoc);
    if (pInMetadata != NULL)
    {
        pOutMetadata = PtxPdf_Metadata_Copy(pOutDoc, pInMetadata);
        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutMetadata, _T("Failed to copy metadata. %s (ErrorCode: 0x%08x)\n"),
                                         szErrorBuff, Ptx_GetLastError());
        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Document_SetMetadata(pOutDoc, pOutMetadata),
                                          _T("Failed to set metadata. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
                                          Ptx_GetLastError());
    }
    else
        GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get metadata. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
                                          Ptx_GetLastError());

    // Viewer settings
    pInViewerSettings = PtxPdf_Document_GetViewerSettings(pInDoc);
    if (pInViewerSettings != NULL)
    {
        pOutViewerSettings = PtxPdfNav_ViewerSettings_Copy(pOutDoc, pInViewerSettings);
        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutViewerSettings,
                                         _T("Failed to copy viewer settings. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
                                         Ptx_GetLastError());
        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Document_SetViewerSettings(pOutDoc, pOutViewerSettings),
                                          _T("Failed to set viewer settings. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
                                          Ptx_GetLastError());
    }
    else
        GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get viewer settings. %s (ErrorCode: 0x%08x)"), szErrorBuff,
                                          Ptx_GetLastError());

    // Associated files (for PDF/A-3 and PDF 2.0 only)
    pInFileRefList = PtxPdf_Document_GetAssociatedFiles(pInDoc);
    GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get associated files of input document. %s (ErrorCode: 0x%08x)\n"),
                                      szErrorBuff, Ptx_GetLastError());
    pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
    GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get associated files of output document. %s (ErrorCode: 0x%08x)\n"),
                                      szErrorBuff, Ptx_GetLastError());
    int nFileRefs = PtxPdf_FileReferenceList_GetCount(pInFileRefList);
    GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get count of associated files. %s (ErrorCode: 0x%08x)\n"),
                                      szErrorBuff, Ptx_GetLastError());
    for (int iFileRef = 0; iFileRef < nFileRefs; iFileRef++)
    {
        pInFileRef = PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef);
        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInFileRef, _T("Failed to get file reference. %s (ErrorCode: 0x%08x)\n"),
                                         szErrorBuff, Ptx_GetLastError());
        pOutFileRef = PtxPdf_FileReference_Copy(pOutDoc, pInFileRef);
        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutFileRef, _T("Failed to copy file reference. %s (ErrorCode: 0x%08x)\n"),
                                         szErrorBuff, Ptx_GetLastError());
        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_FileReferenceList_Add(pOutFileRefList, pOutFileRef),
                                          _T("Failed to add file reference. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
                                          Ptx_GetLastError());
        Ptx_Release(pInFileRef);
        pInFileRef = NULL;
        Ptx_Release(pOutFileRef);
        pOutFileRef = NULL;
    }
    Ptx_Release(pInFileRefList);
    pInFileRefList = NULL;
    Ptx_Release(pOutFileRefList);
    pOutFileRefList = NULL;

    // Plain embedded files
    pInFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(
        pInFileRefList, _T("Failed to get plain embedded files of input document %s (ErrorCode: 0x%08x)\n"),
        szErrorBuff, Ptx_GetLastError());
    pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(
        pInFileRefList, _T("Failed to get plain embedded files of output document %s (ErrorCode: 0x%08x)\n"),
        szErrorBuff, Ptx_GetLastError());
    nFileRefs = PtxPdf_FileReferenceList_GetCount(pInFileRefList);
    GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get count of plain embedded files. %s (ErrorCode: 0x%08x)\n"),
                                      szErrorBuff, Ptx_GetLastError());
    for (int iFileRef = 0; iFileRef < nFileRefs; iFileRef++)
    {
        pInFileRef = PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef);
        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInFileRef, _T("Failed to get file reference. %s (ErrorCode: 0x%08x)\n"),
                                         szErrorBuff, Ptx_GetLastError());
        pOutFileRef = PtxPdf_FileReference_Copy(pOutDoc, pInFileRef);
        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutFileRef, _T("Failed to copy file reference. %s (ErrorCode: 0x%08x)\n"),
                                         szErrorBuff, Ptx_GetLastError());
        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_FileReferenceList_Add(pOutFileRefList, pOutFileRef),
                                          _T("Failed to add file reference. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
                                          Ptx_GetLastError());
        Ptx_Release(pInFileRef);
        pInFileRef = NULL;
        Ptx_Release(pOutFileRef);
        pOutFileRef = NULL;
    }

cleanup:
    if (pInOutputIntent != NULL)
        Ptx_Release(pInOutputIntent);
    if (pOutOutputIntent != NULL)
        Ptx_Release(pOutOutputIntent);
    if (pInMetadata != NULL)
        Ptx_Release(pInMetadata);
    if (pOutMetadata != NULL)
        Ptx_Release(pOutMetadata);
    if (pInViewerSettings != NULL)
        Ptx_Release(pInViewerSettings);
    if (pOutViewerSettings != NULL)
        Ptx_Release(pOutViewerSettings);
    if (pInFileRefList != NULL)
        Ptx_Release(pInFileRefList);
    if (pOutFileRefList != NULL)
        Ptx_Release(pOutFileRefList);
    if (pInFileRef != NULL)
        Ptx_Release(pInFileRef);
    if (pOutFileRef != NULL)
        Ptx_Release(pOutFileRef);
    return iReturnValue;
}
int StampPageNumber(TPtxPdf_Document* pDocument, TPtxPdfContent_Font* pFont,
                    TPtxPdfContent_ContentGenerator* pGenerator, int nPageNo, BOOL bIsLeftPage)
{
    // Objects that need releasing or closing
    TPtxPdfContent_Text*          pText          = NULL;
    TPtxPdfContent_TextGenerator* pTextGenerator = NULL;

    // Create text object
    pText = PtxPdfContent_Text_Create(pDocument);
    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pText, _T("Failed to create text object. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
                                     Ptx_GetLastError());

    // Create text generator
    pTextGenerator = PtxPdfContent_TextGenerator_New(pText, pFont, 8.0, NULL);
    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pTextGenerator, _T("Failed to create text generator. %s (ErrorCode: 0x%08x)\n"),
                                     szErrorBuff, Ptx_GetLastError());

    TCHAR szStampText[50];
    _stprintf(szStampText, _T("Page %d"), nPageNo);

    // Get width of stamp text
    double dStampWidth = PtxPdfContent_TextGenerator_GetWidth(pTextGenerator, szStampText);
    if (dStampWidth == 0.0)
        GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get text width. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
                                          Ptx_GetLastError());

    // Compute position
    TPtxGeomReal_Point point = {
        .dX = bIsLeftPage ? dBorder + 0.5 * dCellWidth - dStampWidth / 2
                          : 2 * dBorder + 1.5 * dCellWidth - dStampWidth / 2,
        .dY = dBorder,
    };

    // Move to position
    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_MoveTo(pTextGenerator, &point),
                                      _T("Failed to move to position. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
                                      Ptx_GetLastError());
    // Add page number
    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_Show(pTextGenerator, szStampText),
                                      _T("Failed to show text. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
                                      Ptx_GetLastError());

    BOOL bClose    = PtxPdfContent_TextGenerator_Close(pTextGenerator);
    pTextGenerator = NULL;
    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(bClose, _T("Failed to close text generator. %s (ErrorCode: 0x%08x)\n"),
                                      szErrorBuff, Ptx_GetLastError());

    // Paint the positioned text
    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_PaintText(pGenerator, pText),
                                      _T("Failed to paint text. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
                                      Ptx_GetLastError());

cleanup:
    if (pText != NULL)
        Ptx_Release(pText);
    if (pTextGenerator != NULL)
        PtxPdfContent_TextGenerator_Close(pTextGenerator);
    return iReturnValue;
}
void ComputeTargetRect(TPtxGeomReal_Rectangle* pRectangle, const TPtxGeomReal_Size* pBBox, BOOL bIsLeftPage)
{
    // Compute factor for fitting page into rectangle
    double dScale       = MIN(dCellWidth / pBBox->dWidth, dCellHeight / pBBox->dHeight);
    double dGroupWidth  = pBBox->dWidth * dScale;
    double dGroupHeight = pBBox->dHeight * dScale;

    // Compute x-value
    double dGroupXPos =
        bIsLeftPage ? dCellLeft + (dCellWidth - dGroupWidth) / 2 : dCellRight + (dCellWidth - dGroupWidth) / 2;

    // Compute y-value
    double dGroupYPos = dCellYPos + (dCellHeight - dGroupHeight) / 2;

    // Set rectangle
    pRectangle->dLeft   = dGroupXPos;
    pRectangle->dBottom = dGroupYPos;
    pRectangle->dRight  = dGroupXPos + dGroupWidth;
    pRectangle->dTop    = dGroupYPos + dGroupHeight;
}
int CreateBooklet(TPtxPdf_PageList* pInDocList, TPtxPdf_Document* pOutDoc, TPtxPdf_PageList* pOutDocList,
                  int nLeftPageIndex, int nRightPageIndex, TPtxPdfContent_Font* pFont)
{
    // Objects that need releasing or closing
    TPtxPdf_PageCopyOptions*         pCopyOptions = NULL;
    TPtxPdf_Page*                    pOutPage     = NULL;
    TPtxPdfContent_Content*          pContent     = NULL;
    TPtxPdfContent_ContentGenerator* pGenerator   = NULL;
    TPtxPdf_Page*                    pInPage      = NULL;
    TPtxPdfContent_Group*            pGroup       = NULL;

    // Configure copy options
    pCopyOptions = PtxPdf_PageCopyOptions_New();

    // Create page object
    pOutPage = PtxPdf_Page_Create(pOutDoc, &pageSize);
    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage, _T("Failed to create page object. %s (ErrorCode: 0x%08x)\n"),
                                     szErrorBuff, Ptx_GetLastError());

    // Create content generator
    pContent = PtxPdf_Page_GetContent(pOutPage);
    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pContent, _T("Failed to get content. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
                                     Ptx_GetLastError());
    pGenerator = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGenerator, _T("Failed to create content generator. %s (ErrorCode: 0x%08x)\n"),
                                     szErrorBuff, Ptx_GetLastError());

    int nPageCount = PtxPdf_PageList_GetCount(pInDocList);
    GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get page list count. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
                                      Ptx_GetLastError());

    // Left page
    if (nLeftPageIndex lt; nPageCount)
    {
        // Get the input page
        pInPage = PtxPdf_PageList_Get(pInDocList, nLeftPageIndex);
        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPage, _T("Failed to get page. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
                                         Ptx_GetLastError());

        // Copy page from input to output
        pGroup = PtxPdfContent_Group_CopyFromPage(pOutDoc, pInPage, pCopyOptions);
        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGroup, _T("Failed to copy page as group. %s (ErrorCode: 0x%08x)\n"),
                                         szErrorBuff, Ptx_GetLastError());

        // Compute group location
        TPtxGeomReal_Size groupSize;
        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_Group_GetSize(pGroup, &groupSize),
                                          _T("Failed to get group size. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
                                          Ptx_GetLastError());
        TPtxGeomReal_Rectangle targetRect;
        ComputeTargetRect(&targetRect, &groupSize, TRUE);

        // Paint group at location
        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(
            PtxPdfContent_ContentGenerator_PaintGroup(pGenerator, pGroup, &targetRect, NULL),
            _T("Failed to paint group. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());

        // Add page number to page
        if (StampPageNumber(pOutDoc, pFont, pGenerator, nLeftPageIndex + 1, TRUE) != 0)
            goto cleanup;

        Ptx_Release(pInPage);
        pInPage = NULL;
        Ptx_Release(pGroup);
        pGroup = NULL;
    }

    // Right page
    if (nRightPageIndex lt; nPageCount)
    {
        // Get the input Page
        pInPage = PtxPdf_PageList_Get(pInDocList, nRightPageIndex);
        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPage, _T("Failed to get page. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
                                         Ptx_GetLastError());

        // Copy page from input to output
        pGroup = PtxPdfContent_Group_CopyFromPage(pOutDoc, pInPage, pCopyOptions);
        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGroup, _T("Failed to copy page as group. %s (ErrorCode: 0x%08x)\n"),
                                         szErrorBuff, Ptx_GetLastError());

        // Compute group location
        TPtxGeomReal_Size groupSize;
        PtxPdfContent_Group_GetSize(pGroup, &groupSize);
        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_Group_GetSize(pGroup, &groupSize),
                                          _T("Failed to get group size. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
                                          Ptx_GetLastError());
        TPtxGeomReal_Rectangle targetRect;
        ComputeTargetRect(&targetRect, &groupSize, FALSE);

        // Paint group on the Computed rectangle
        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(
            PtxPdfContent_ContentGenerator_PaintGroup(pGenerator, pGroup, &targetRect, NULL),
            _T("Failed to paint group. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());

        // Add page number to page
        if (StampPageNumber(pOutDoc, pFont, pGenerator, nRightPageIndex + 1, FALSE) != 0)
            goto cleanup;
    }

    BOOL bClose = PtxPdfContent_ContentGenerator_Close(pGenerator);
    pGenerator  = NULL;
    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(bClose, _T("Failed to close content generator. %s (ErrorCode: 0x%08x)\n"),
                                      szErrorBuff, Ptx_GetLastError());

    // Add page to output document
    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutDocList, pOutPage),
                                      _T("Failed to add page to output document. %s (ErrorCode: 0x%08x)\n"),
                                      szErrorBuff, Ptx_GetLastError());

cleanup:
    if (pGenerator != NULL)
        PtxPdfContent_ContentGenerator_Close(pGenerator);
    if (pCopyOptions != NULL)
        Ptx_Release(pCopyOptions);
    if (pOutPage != NULL)
        Ptx_Release(pOutPage);
    if (pContent != NULL)
        Ptx_Release(pContent);
    if (pInPage != NULL)
        Ptx_Release(pInPage);
    if (pGroup != NULL)
        Ptx_Release(pGroup);
    return iReturnValue;
}
サンプル・プロジェクトの実行手順を参照してください
// Open input document
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))

// Create output document 
using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
{
    // Copy document-wide data
    CopyDocumentData(inDoc, outDoc);

    // Create a font
    Font font = Font.CreateFromSystem(outDoc, "Arial", "Italic", true);

    // Copy pages
    PageList inPages = inDoc.Pages;
    PageList outPages = outDoc.Pages;
    int numberOfSheets = (inPages.Count + 3) / 4;

    for (int sheetNumber = 0; sheetNumber lt; numberOfSheets; ++sheetNumber)
    {

        // Add on front side
        CreateBooklet(inPages, outDoc, outPages, 4 * numberOfSheets - 2 * sheetNumber - 1,
            2 * sheetNumber, font);

        // Add on back side
        CreateBooklet(inPages, outDoc, outPages, 2 * sheetNumber + 1,
            4 * numberOfSheets - 2 * sheetNumber - 2, font);
    }
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
    // Copy document-wide data

    // Output intent
    if (inDoc.OutputIntent != null)
        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);

    // Metadata
    outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);

    // Viewer settings
    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);

    // Associated files (for PDF/A-3 and PDF 2.0 only)
    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));

    // Plain embedded files
    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
private static void CreateBooklet(PageList inPages, Document outDoc, PageList outPages, int leftPageIndex,
    int rightPageIndex, Font font)
{
    // Define page copy options
    PageCopyOptions copyOptions = new PageCopyOptions();

    // Create page object
    Page outpage = Page.Create(outDoc, PageSize);

    // Create content generator
    using (ContentGenerator generator = new ContentGenerator(outpage.Content, false))
    {
        // Left page 
        if (leftPageIndex lt; inPages.Count)
        {
            // Copy page from input to output
            Page leftPage = inPages[leftPageIndex];
            Group leftGroup = Group.CopyFromPage(outDoc, leftPage, copyOptions);

            // Paint group on the calculated rectangle
            generator.PaintGroup(leftGroup, ComputTargetRect(leftGroup.Size, true), null);

            // Add page number to page
            StampPageNumber(outDoc, font, generator, leftPageIndex + 1, true);
        }

        // Right page
        if (rightPageIndex lt; inPages.Count)
        {
            // Copy page from input to output
            Page rigthPage = inPages[rightPageIndex];
            Group rightGroup = Group.CopyFromPage(outDoc, rigthPage, copyOptions);

            // Paint group on the calculated rectangle
            generator.PaintGroup(rightGroup, ComputTargetRect(rightGroup.Size, false), null);

            // Add page number to page
            StampPageNumber(outDoc, font, generator, rightPageIndex + 1, false);
        }
    }
    // Add page to output document
    outPages.Add(outpage);
}
private static Rectangle ComputTargetRect(Size bbox, bool isLeftPage)
{
    // Calculate factor for fitting page into rectangle
    double scale = Math.Min(CellWidth / bbox.Width, CellHeight / bbox.Height);
    double groupWidth = bbox.Width * scale;
    double groupHeight = bbox.Height * scale;

    // Calculate x-value
    double groupXPos = isLeftPage ? CellLeft + (CellWidth - groupWidth) / 2 :
                                    CellRight + (CellWidth - groupWidth) / 2;

    // Calculate y-value
    double groupYPos = CellYPos + (CellHeight - groupHeight) / 2;

    // Calculate rectangle
    return new Rectangle
    {
        Left = groupXPos,
        Bottom = groupYPos,
        Right = groupXPos + groupWidth,
        Top = groupYPos + groupHeight
    };
}
private static void StampPageNumber(Document document, Font font, ContentGenerator generator,
    int PageNo, bool isLeftPage)
{
    // Create text object
    Text text = Text.Create(document);

    // Create text generator
    using (TextGenerator textgenerator = new TextGenerator(text, font, 8, null))
    {
        string stampText = string.Format("Page {0}", PageNo);

        // Get width of stamp text
        double width = textgenerator.GetWidth(stampText);

        // Calculate position
        double x = isLeftPage ? Border + 0.5 * CellWidth - width / 2 :
                                2 * Border + 1.5 * CellWidth - width / 2;
        double y = Border;

        // Move to position
        textgenerator.MoveTo(new Point { X = x, Y = y});

        // Add page number
        textgenerator.Show(stampText);
    }
    // Paint the positioned text
    generator.PaintText(text);
}
サンプル・プロジェクトの実行手順を参照してください
def copy_document_data(in_doc: Document, out_doc: Document):
    # Copy document-wide data

    # Output intent
    if in_doc.output_intent is not None:
        in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)

    # Metadata
    out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)

    # Viewer settings
    out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)

    # Associated files (for PDF/A-3 and PDF 2.0 only)
    outAssociatedFiles = out_doc.associated_files
    for in_file_ref in in_doc.associated_files:
        outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))

    # Plain embedded files
    out_embedded_files = out_doc.plain_embedded_files
    for in_file_ref in in_doc.plain_embedded_files:
        out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))
def compute_target_rect(bbox: Size, is_left_page: bool) -> Rectangle:
    # Calculate factor for fitting page into rectangle
    scale = min(cell_width / bbox.width, cell_height / bbox.height)
    group_width = bbox.width * scale
    group_height = bbox.height * scale

    # Calculate x-value
    group_x_pos = cell_left + (cell_width - group_width) / 2 if is_left_page else cell_right + (cell_width - group_width) / 2

    # Calculate y-value
    group_y_pos = cell_y_pos + (cell_height - group_height) / 2

    # Calculate rectangle
    return Rectangle(
        left=group_x_pos,
        bottom=group_y_pos,
        right=group_x_pos + group_width,
        top=group_y_pos + group_height,
    )
def stamp_page_number(document: Document, font: Font, generator: ContentGenerator, page_no: int, is_left_page: bool):
    # Create text object
    text = Text.create(document)

    # Create text generator
    with TextGenerator(text, font, 8.0, None) as text_generator:
        stamp_text = f"Page {page_no}"

        # Get width of stamp text
        width = text_generator.get_width(stamp_text)

        # Calculate position
        x = border + 0.5 * cell_width - width / 2 if is_left_page else 2 * border + 1.5 * cell_width - width / 2
        y = border

        # Move to position
        text_generator.move_to(Point(x=x, y=y))

        # Add page number
        text_generator.show(stamp_text)

    # Paint the positioned text
    generator.paint_text(text)
def create_booklet(in_pages: PageList, out_doc: Document, out_pages: PageList, left_page_index: int, right_page_index: int, font: Font):
    # Define page copy options
    copy_options = PageCopyOptions()

    # Create page object
    out_page = Page.create(out_doc, page_size)

    # Create content generator
    with ContentGenerator(out_page.content, False) as generator:
        # Left page
        if left_page_index lt; len(in_pages):
            # Copy page from input to output
            left_page = in_pages[left_page_index]
            left_group = Group.copy_from_page(out_doc, left_page, copy_options)

            # Paint group into target rectangle
            generator.paint_group(left_group, compute_target_rect(left_group.size, True), None)

            # Add page number to page
            stamp_page_number(out_doc, font, generator, left_page_index + 1, True)

        # Right page
        if right_page_index lt; len(in_pages):
            # Copy page from input to output
            right_page = in_pages[right_page_index]
            right_group = Group.copy_from_page(out_doc, right_page, copy_options)

            # Paint group on the calculated rectangle
            generator.paint_group(right_group, compute_target_rect(right_group.size, False), None)

            # Add page number to page
            stamp_page_number(out_doc, font, generator, right_page_index + 1, False)

    # Add page to output document
    out_pages.append(out_page)
# Define global variables
page_size = Size(1190.0, 842.0)  # A3 portrait
border = 10.0
cell_width = (page_size.width - 3 * border) / 2
cell_height = page_size.height - 2 * border
cell_left = border
cell_right = 2 * border + cell_width
cell_y_pos = border

# Open input document
with io.FileIO(input_file_path, "rb") as in_stream:
    with Document.open(in_stream, None) as in_doc:

        # Create output document
        with io.FileIO(output_file_path, "wb+") as output_stream:
            with Document.create(output_stream, in_doc.conformance, None) as out_doc:

                # Copy document-wide data
                copy_document_data(in_doc, out_doc)

                # Create a font
                font = Font.create_from_system(out_doc, "Arial", "Italic", True)

                # Copy pages
                in_pages = in_doc.pages
                out_pages = out_doc.pages
                number_of_sheets = (len(in_pages) + 3) // 4

                for sheet_number in range(number_of_sheets):
                    # Add front side
                    create_booklet(in_pages, out_doc, out_pages, 4 * number_of_sheets - 2 * sheet_number - 1, 2 * sheet_number, font)
                    # Add back side
                    create_booklet(in_pages, out_doc, out_pages, 2 * sheet_number + 1, 4 * number_of_sheets - 2 * sheet_number - 2, font)

他の機能サンプルを参照してください。

お問い合わせ、ご質問、技術サポート

質問のページからお送りいただくようお願いします。
または、メールでsupport@trustss.co.jpあてにお送りください。


ご購入前の技術的質問も無償で対応します。サポート受付ページからお願いします。

> PDF Structure (PDF構成)

> PDF Imager-LP (画像化)

> PDF Stamper (電子印鑑)

> Pdftools SDK

- サンプル・コード
- Pdftools SDKサンプルの利用手順
- Toolbox Add-on
- Toolbox Add-onサンプルの利用手順
> Pdftools SDK APIリファレンス
- その他のAPI及びコマンドラインツール
> PDF SDK オープンソースと有償ライブラリ